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

  1. Newsgroups: comp.sources.x
  2. From: envbvs@epb9.lbl.gov (Brian V. Smith)
  3. Subject: v19i125:  xfig - Draw amd manipulate objects in an X-Window, Part13/27
  4. Message-ID: <1993May21.021510.6255@sparky.imd.sterling.com>
  5. X-Md4-Signature: 95ef26403d95a1dc6ac32a38c3594e95
  6. Sender: chris@sparky.imd.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Fri, 21 May 1993 02:15:10 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 125
  13. Archive-name: xfig/part13
  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 13 (of 27)."
  24. # Contents:  e_movept.c u_list.c u_search.c
  25. # Wrapped by envbvs@epb9.lbl.gov.lbl.gov on Mon May  3 12:05:56 1993
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'e_movept.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'e_movept.c'\"
  29. else
  30. echo shar: Extracting \"'e_movept.c'\" \(19377 characters\)
  31. sed "s/^X//" >'e_movept.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 "mode.h"
  47. X#include "object.h"
  48. X#include "paintop.h"
  49. X#include "u_draw.h"
  50. X#include "u_search.h"
  51. X#include "u_create.h"
  52. X#include "u_elastic.h"
  53. X#include "u_list.h"
  54. X#include "u_undo.h"
  55. X#include "w_canvas.h"
  56. X#include "w_mousefun.h"
  57. X
  58. Xextern void     force_anglegeom(), force_noanglegeom();
  59. X
  60. X/* local routine declarations */
  61. X
  62. Xstatic F_point *moved_point;
  63. X
  64. Xstatic Boolean    init_ellipsepointmoving();
  65. Xstatic int    init_arcpointmoving();
  66. Xstatic int    init_linepointmoving();
  67. Xstatic int    init_splinepointmoving();
  68. Xstatic int    init_compoundpointmoving();
  69. X
  70. Xstatic int    relocate_arcpoint();
  71. Xstatic int    relocate_ellipsepoint();
  72. Xstatic int    relocate_linepoint();
  73. Xstatic int    relocate_splinepoint();
  74. Xstatic int    assign_newboxpoint();
  75. X
  76. Xstatic int    init_move_point();
  77. Xstatic int    init_arb_move_point();
  78. Xstatic int    init_stretch_move_point();
  79. X
  80. Xstatic int    fix_movedarcpoint();
  81. Xstatic int    fix_movedellipsepoint();
  82. Xstatic int    fix_movedsplinepoint();
  83. Xstatic int    fix_box();
  84. Xstatic int    fix_movedlinepoint();
  85. Xstatic int    fix_movedlatexlinepoint();
  86. X
  87. Xstatic int    cancel_movedarcpoint();
  88. Xstatic int    cancel_movedellipsepoint();
  89. Xstatic int    cancel_movedsplinepoint();
  90. Xstatic int    cancel_box();
  91. Xstatic int    cancel_movedlinepoint();
  92. X
  93. Xmove_point_selected()
  94. X{
  95. X    set_mousefun("move point", "horiz/vert move", "");
  96. X    canvas_kbd_proc = null_proc;
  97. X    canvas_locmove_proc = null_proc;
  98. X    init_searchproc_left(init_arb_move_point);
  99. X    init_searchproc_middle(init_stretch_move_point);
  100. X    canvas_leftbut_proc = point_search_left;
  101. X    canvas_middlebut_proc = point_search_middle;
  102. X    canvas_rightbut_proc = null_proc;
  103. X    set_cursor(pick9_cursor);
  104. X    force_anglegeom();
  105. X}
  106. X
  107. Xstatic
  108. Xinit_arb_move_point(obj, type, x, y, p, q)
  109. X    char       *obj;
  110. X    int            type, x, y;
  111. X    F_point       *p, *q;
  112. X{
  113. X    constrained = MOVE_ARB;
  114. X    init_move_point(obj, type, x, y, p, q);
  115. X    set_mousefun("new posn", "", "cancel");
  116. X    draw_mousefun_canvas();
  117. X    canvas_middlebut_proc = null_proc;
  118. X}
  119. X
  120. Xstatic
  121. Xinit_stretch_move_point(obj, type, x, y, p, q)
  122. X    char       *obj;
  123. X    int            type, x, y;
  124. X    F_point       *p, *q;
  125. X{
  126. X    constrained = MOVE_HORIZ_VERT;
  127. X    init_move_point(obj, type, x, y, p, q);
  128. X    set_mousefun("", "new posn", "cancel");
  129. X    draw_mousefun_canvas();
  130. X    canvas_middlebut_proc = canvas_leftbut_proc;
  131. X    canvas_leftbut_proc = null_proc;
  132. X}
  133. X
  134. Xstatic
  135. Xinit_move_point(obj, type, x, y, p, q)
  136. X    char       *obj;
  137. X    int            type, x, y;
  138. X    F_point       *p, *q;
  139. X{
  140. X    left_point = p;
  141. X    moved_point = q;
  142. X    switch (type) {
  143. X    case O_POLYLINE:
  144. X    cur_l = (F_line *) obj;
  145. X    right_point = q->next;
  146. X    init_linepointmoving();
  147. X    break;
  148. X    case O_SPLINE:
  149. X    cur_s = (F_spline *) obj;
  150. X    right_point = q->next;
  151. X    init_splinepointmoving();
  152. X    break;
  153. X    case O_ELLIPSE:
  154. X    force_noanglegeom();
  155. X    /* dirty trick - arcpoint_num is stored in p */
  156. X    movedpoint_num = (int) p;
  157. X    cur_e = (F_ellipse *) obj;
  158. X    if (!init_ellipsepointmoving()) /* selected center, ignore */
  159. X        return;
  160. X    break;
  161. X    case O_ARC:
  162. X    force_noanglegeom();
  163. X    /* dirty trick - arcpoint_num is stored in p */
  164. X    movedpoint_num = (int) p;
  165. X    cur_a = (F_arc *) obj;
  166. X    init_arcpointmoving();
  167. X    break;
  168. X    case O_COMPOUND:
  169. X    force_noanglegeom();
  170. X    /* dirty trick - posn of corner is stored in p and q */
  171. X    cur_x = (int) p;
  172. X    cur_y = (int) q;
  173. X    cur_c = (F_compound *) obj;
  174. X    init_compoundpointmoving();
  175. X    break;
  176. X    default:
  177. X    return;
  178. X    }
  179. X}
  180. X
  181. Xstatic
  182. Xwrapup_movepoint()
  183. X{
  184. X    reset_action_on();
  185. X    move_point_selected();
  186. X    draw_mousefun_canvas();
  187. X}
  188. X
  189. X/*************************  ellipse  *******************************/
  190. X
  191. Xstatic        Boolean
  192. Xinit_ellipsepointmoving()
  193. X{
  194. X    double        dx, dy, l;
  195. X
  196. X    if (constrained &&
  197. X    (cur_e->type == T_CIRCLE_BY_DIA || cur_e->type == T_CIRCLE_BY_RAD)) {
  198. X    put_msg("Constrained move not supported for CIRCLES");
  199. X    return False;        /* abort - constrained move for circle not
  200. X                 * needed */
  201. X    }
  202. X    if (movedpoint_num == 0) {
  203. X    if (cur_e->type == T_ELLIPSE_BY_RAD ||
  204. X        cur_e->type == T_CIRCLE_BY_RAD) {
  205. X        put_msg("Cannot move CENTER point");
  206. X        return False;    /* abort - center point is selected */
  207. X    }
  208. X    cur_x = cur_e->start.x;
  209. X    cur_y = cur_e->start.y;
  210. X    fix_x = cur_e->end.x;
  211. X    fix_y = cur_e->end.y;
  212. X    } else {
  213. X    cur_x = cur_e->end.x;
  214. X    cur_y = cur_e->end.y;
  215. X    fix_x = cur_e->start.x;
  216. X    fix_y = cur_e->start.y;
  217. X    }
  218. X    if (constrained) {
  219. X    dx = cur_x - fix_x;
  220. X    dy = cur_y - fix_y;
  221. X    l = sqrt(dx * dx + dy * dy);
  222. X    cosa = fabs(dx / l);
  223. X    sina = fabs(dy / l);
  224. X    }
  225. X    cur_angle = cur_e->angle;
  226. X    set_action_on();
  227. X    toggle_ellipsemarker(cur_e);
  228. X    draw_ellipse(cur_e, ERASE);
  229. X    switch (cur_e->type) {
  230. X    case T_ELLIPSE_BY_RAD:
  231. X    canvas_locmove_proc = constrained_resizing_ebr;
  232. X    elastic_ebr();
  233. X    break;
  234. X    case T_CIRCLE_BY_RAD:
  235. X    canvas_locmove_proc = resizing_cbr;
  236. X    elastic_cbr();
  237. X    break;
  238. X    case T_ELLIPSE_BY_DIA:
  239. X    canvas_locmove_proc = constrained_resizing_ebd;
  240. X    elastic_ebd();
  241. X    break;
  242. X    case T_CIRCLE_BY_DIA:
  243. X    canvas_locmove_proc = resizing_cbd;
  244. X    elastic_cbd();
  245. X    break;
  246. X    }
  247. X    from_x = cur_x;
  248. X    from_y = cur_y;
  249. X    set_temp_cursor(crosshair_cursor);
  250. X    canvas_leftbut_proc = fix_movedellipsepoint;
  251. X    canvas_rightbut_proc = cancel_movedellipsepoint;
  252. X    return True;        /* all is Ok */
  253. X}
  254. X
  255. Xstatic
  256. Xcancel_movedellipsepoint()
  257. X{
  258. X    switch (cur_e->type) {
  259. X    case T_ELLIPSE_BY_RAD:
  260. X    elastic_ebr();
  261. X    break;
  262. X    case T_CIRCLE_BY_RAD:
  263. X    elastic_cbr();
  264. X    break;
  265. X    case T_ELLIPSE_BY_DIA:
  266. X    elastic_ebd();
  267. X    break;
  268. X    case T_CIRCLE_BY_DIA:
  269. X    elastic_cbd();
  270. X    break;
  271. X    }
  272. X    draw_ellipse(cur_e, PAINT);
  273. X    toggle_ellipsemarker(cur_e);
  274. X    wrapup_movepoint();
  275. X}
  276. X
  277. Xstatic
  278. Xfix_movedellipsepoint(x, y)
  279. X    int            x, y;
  280. X{
  281. X    switch (cur_e->type) {
  282. X    case T_ELLIPSE_BY_RAD:
  283. X    elastic_ebr();
  284. X    break;
  285. X    case T_CIRCLE_BY_RAD:
  286. X    elastic_cbr();
  287. X    break;
  288. X    case T_ELLIPSE_BY_DIA:
  289. X    elastic_ebd();
  290. X    break;
  291. X    case T_CIRCLE_BY_DIA:
  292. X    elastic_cbd();
  293. X    break;
  294. X    }
  295. X    adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  296. X    new_e = copy_ellipse(cur_e);
  297. X    relocate_ellipsepoint(new_e, cur_x, cur_y, movedpoint_num);
  298. X    change_ellipse(cur_e, new_e);
  299. X    toggle_ellipsemarker(new_e);
  300. X    wrapup_movepoint();
  301. X}
  302. X
  303. Xstatic
  304. Xrelocate_ellipsepoint(ellipse, x, y, point_num)
  305. X    F_ellipse       *ellipse;
  306. X    int            x, y, point_num;
  307. X{
  308. X    int            dx, dy;
  309. X
  310. X    set_temp_cursor(wait_cursor);
  311. X    draw_ellipse(ellipse, ERASE);
  312. X    if (point_num == 0) {    /* starting point is selected  */
  313. X    fix_x = ellipse->end.x;
  314. X    fix_y = ellipse->end.y;
  315. X    ellipse->start.x = x;
  316. X    ellipse->start.y = y;
  317. X    } else {
  318. X    fix_x = ellipse->start.x;
  319. X    fix_y = ellipse->start.y;
  320. X    ellipse->end.x = x;
  321. X    ellipse->end.y = y;
  322. X    }
  323. X    cur_angle = ellipse->angle;
  324. X    switch (ellipse->type) {
  325. X    case T_ELLIPSE_BY_RAD:
  326. X    ellipse->radiuses.x = abs(x - fix_x);
  327. X    ellipse->radiuses.y = abs(y - fix_y);
  328. X    break;
  329. X    case T_CIRCLE_BY_RAD:
  330. X    dx = fix_x - x;
  331. X    dy = fix_y - y;
  332. X    ellipse->radiuses.x = sqrt((double) (dx * dx + dy * dy)) + .5;
  333. X    ellipse->radiuses.y = ellipse->radiuses.x;
  334. X    break;
  335. X    case T_ELLIPSE_BY_DIA:
  336. X    ellipse->center.x = (fix_x + x) / 2;
  337. X    ellipse->center.y = (fix_y + y) / 2;
  338. X    ellipse->radiuses.x = abs(ellipse->center.x - fix_x);
  339. X    ellipse->radiuses.y = abs(ellipse->center.y - fix_y);
  340. X    break;
  341. X    case T_CIRCLE_BY_DIA:
  342. X    dx = ellipse->center.x = (fix_x + x) / 2 + .5;
  343. X    dy = ellipse->center.y = (fix_y + y) / 2 + .5;
  344. X    dx -= x;
  345. X    dy -= y;
  346. X    ellipse->radiuses.x = sqrt((double) (dx * dx + dy * dy)) + .5;
  347. X    ellipse->radiuses.y = ellipse->radiuses.x;
  348. X    break;
  349. X    }
  350. X    /* if this WAS an ellipse and is NOW a circle (radii are equal), change type */
  351. X    if (ellipse->type == T_ELLIPSE_BY_RAD || ellipse->type == T_ELLIPSE_BY_DIA) {
  352. X    if (ellipse->radiuses.x == ellipse->radiuses.y)
  353. X        ellipse->type += 2;
  354. X    }
  355. X    draw_ellipse(ellipse, PAINT);
  356. X    reset_cursor();
  357. X}
  358. X
  359. X/***************************  arc  *********************************/
  360. X
  361. Xstatic
  362. Xinit_arcpointmoving()
  363. X{
  364. X    set_action_on();
  365. X    toggle_arcmarker(cur_a);
  366. X    cur_x = cur_a->point[movedpoint_num].x;
  367. X    cur_y = cur_a->point[movedpoint_num].y;
  368. X    set_temp_cursor(crosshair_cursor);
  369. X    win_setmouseposition(canvas_win, cur_x, cur_y);
  370. X    elastic_arclink();
  371. X    canvas_locmove_proc = reshaping_arc;
  372. X    canvas_leftbut_proc = fix_movedarcpoint;
  373. X    canvas_rightbut_proc = cancel_movedarcpoint;
  374. X}
  375. X
  376. Xstatic
  377. Xcancel_movedarcpoint()
  378. X{
  379. X    elastic_arclink();
  380. X    toggle_arcmarker(cur_a);
  381. X    wrapup_movepoint();
  382. X}
  383. X
  384. Xstatic
  385. Xfix_movedarcpoint(x, y)
  386. X    int            x, y;
  387. X{
  388. X    elastic_arclink();
  389. X    adjust_pos(x, y, cur_a->point[movedpoint_num].x,
  390. X           cur_a->point[movedpoint_num].y, &x, &y);
  391. X    new_a = copy_arc(cur_a);
  392. X    relocate_arcpoint(new_a, x, y, movedpoint_num);
  393. X    change_arc(cur_a, new_a);
  394. X    toggle_arcmarker(new_a);
  395. X    wrapup_movepoint();
  396. X}
  397. X
  398. Xstatic
  399. Xrelocate_arcpoint(arc, x, y, movedpoint_num)
  400. X    F_arc       *arc;
  401. X    int            x, y, movedpoint_num;
  402. X{
  403. X    float        xx, yy;
  404. X    F_pos        p[3];
  405. X
  406. X    p[0] = arc->point[0];
  407. X    p[1] = arc->point[1];
  408. X    p[2] = arc->point[2];
  409. X    p[movedpoint_num].x = x;
  410. X    p[movedpoint_num].y = y;
  411. X    if (compute_arccenter(p[0], p[1], p[2], &xx, &yy)) {
  412. X    set_temp_cursor(wait_cursor);
  413. X    draw_arc(arc, ERASE);    /* erase old arc */
  414. X    arc->point[movedpoint_num].x = x;
  415. X    arc->point[movedpoint_num].y = y;
  416. X    arc->center.x = xx;
  417. X    arc->center.y = yy;
  418. X    arc->direction = compute_direction(p[0], p[1], p[2]);
  419. X    draw_arc(arc, PAINT);    /* draw new arc */
  420. X    reset_cursor();
  421. X    }
  422. X}
  423. X
  424. X/**************************  spline  *******************************/
  425. X
  426. Xstatic
  427. Xinit_splinepointmoving()
  428. X{
  429. X    F_point       *p;
  430. X
  431. X    set_action_on();
  432. X    toggle_splinemarker(cur_s);
  433. X    from_x = cur_x = moved_point->x;
  434. X    from_y = cur_y = moved_point->y;
  435. X    set_temp_cursor(crosshair_cursor);
  436. X    if (open_spline(cur_s)) {
  437. X    if (left_point == NULL || right_point == NULL) {
  438. X            if (left_point != NULL) {
  439. X                fix_x = left_point->x;
  440. X                fix_y = left_point->y;
  441. X            } else if (right_point != NULL) {
  442. X                fix_x = right_point->x;
  443. X                fix_y = right_point->y;
  444. X            }
  445. X        if (latexline_mode || latexarrow_mode) {
  446. X                canvas_locmove_proc = latex_line;
  447. X                cur_latexcursor = crosshair_cursor;
  448. X            } else if (mountain_mode || manhattan_mode) {
  449. X                canvas_locmove_proc = constrainedangle_line;
  450. X            } else {
  451. X                /* freehand line */
  452. X                canvas_locmove_proc = reshaping_line;
  453. X            }
  454. X    } else {
  455. X            /* linelink, always freehand */
  456. X        force_noanglegeom();
  457. X        canvas_locmove_proc = reshaping_line;
  458. X    }
  459. X    } else {
  460. X    /* must be closed spline */
  461. X    force_noanglegeom();
  462. X    canvas_locmove_proc = reshaping_line;
  463. X    if (left_point == NULL) {
  464. X        for (left_point = right_point, p = left_point->next;
  465. X         p->next != NULL;
  466. X         left_point = p, p = p->next);
  467. X    }
  468. X    }
  469. X    elastic_linelink();
  470. X    canvas_leftbut_proc = fix_movedsplinepoint;
  471. X    canvas_rightbut_proc = cancel_movedsplinepoint;
  472. X}
  473. X
  474. Xstatic
  475. Xcancel_movedsplinepoint()
  476. X{
  477. X    elastic_linelink();
  478. X    toggle_splinemarker(cur_s);
  479. X    wrapup_movepoint();
  480. X}
  481. X
  482. Xstatic
  483. Xfix_movedsplinepoint(x, y)
  484. X    int            x, y;
  485. X{
  486. X    (*canvas_locmove_proc) (x, y);
  487. X    elastic_linelink();
  488. X    old_s = copy_spline(cur_s);
  489. X    clean_up();
  490. X    set_latestspline(old_s);
  491. X    set_action_object(F_CHANGE, O_SPLINE);
  492. X    old_s->next = cur_s;
  493. X    relocate_splinepoint(cur_s, cur_x, cur_y, moved_point);
  494. X    toggle_splinemarker(cur_s);
  495. X    wrapup_movepoint();
  496. X}
  497. X
  498. Xstatic
  499. Xrelocate_splinepoint(s, x, y, moved_point)
  500. X    F_spline       *s;
  501. X    int            x, y;
  502. X    F_point       *moved_point;
  503. X{
  504. X    set_temp_cursor(wait_cursor);
  505. X    draw_spline(s, ERASE);    /* erase old spline */
  506. X    moved_point->x = x;
  507. X    moved_point->y = y;
  508. X    if (closed_spline(s)) {
  509. X    left_point->next->x = x;
  510. X    left_point->next->y = y;
  511. X    }
  512. X    if (int_spline(s))
  513. X    remake_control_points(s);
  514. X    draw_spline(s, PAINT);    /* draw spline with moved point */
  515. X    set_modifiedflag();
  516. X    reset_cursor();
  517. X}
  518. X
  519. X/***************************  compound    ********************************/
  520. X
  521. Xstatic        prescale_compound(), cancel_compound();
  522. X
  523. Xstatic
  524. Xinit_compoundpointmoving()
  525. X{
  526. X    double        dx, dy, l;
  527. X
  528. X    set_action_on();
  529. X    if (cur_x == cur_c->nwcorner.x)
  530. X    fix_x = cur_c->secorner.x;
  531. X    else
  532. X    fix_x = cur_c->nwcorner.x;
  533. X    if (cur_y == cur_c->nwcorner.y)
  534. X    fix_y = cur_c->secorner.y;
  535. X    else
  536. X    fix_y = cur_c->nwcorner.y;
  537. X    from_x = cur_x;
  538. X    from_y = cur_y;
  539. X    toggle_compoundmarker(cur_c);
  540. X    draw_compoundelements(cur_c, ERASE);
  541. X    set_temp_cursor(crosshair_cursor);
  542. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  543. X    if (constrained) {
  544. X    dx = cur_x - fix_x;
  545. X    dy = cur_y - fix_y;
  546. X    l = sqrt(dx * dx + dy * dy);
  547. X    cosa = fabs(dx / l);
  548. X    sina = fabs(dy / l);
  549. X    }
  550. X    canvas_locmove_proc = constrained_resizing_box;
  551. X    canvas_leftbut_proc = prescale_compound;
  552. X    canvas_rightbut_proc = cancel_compound;
  553. X}
  554. X
  555. Xstatic
  556. Xcancel_compound()
  557. X{
  558. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  559. X    draw_compoundelements(cur_c, PAINT);
  560. X    toggle_compoundmarker(cur_c);
  561. X    wrapup_movepoint();
  562. X}
  563. X
  564. Xextern        scale_compound();
  565. X
  566. Xstatic
  567. Xprescale_compound(x, y)
  568. X    int            x, y;
  569. X{
  570. X    float        scalex, scaley;
  571. X
  572. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  573. X    adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  574. X
  575. X    scalex = ((float) (cur_x - fix_x)) / (from_x - fix_x);
  576. X    scaley = ((float) (cur_y - fix_y)) / (from_y - fix_y);
  577. X    scale_compound(cur_c, scalex, scaley, fix_x, fix_y);
  578. X
  579. X    draw_compoundelements(cur_c, PAINT);
  580. X    set_lastposition(from_x, from_y);
  581. X    set_newposition(cur_x, cur_y);
  582. X    clean_up();
  583. X    set_action_object(F_SCALE, O_COMPOUND);
  584. X    set_latestcompound(cur_c);
  585. X    toggle_compoundmarker(cur_c);
  586. X    set_modifiedflag();
  587. X    reset_cursor();
  588. X    wrapup_movepoint();
  589. X}
  590. X
  591. X/***************************  line  ********************************/
  592. X
  593. Xstatic
  594. Xinit_linepointmoving()
  595. X{
  596. X    F_point       *p;
  597. X
  598. X    set_action_on();
  599. X    toggle_linemarker(cur_l);
  600. X    from_x = cur_x = moved_point->x;
  601. X    from_y = cur_y = moved_point->y;
  602. X    set_temp_cursor(crosshair_cursor);
  603. X    switch (cur_l->type) {
  604. X    case T_POLYGON:
  605. X    if (left_point == NULL)
  606. X        for (left_point = right_point, p = left_point->next;
  607. X         p->next != NULL;
  608. X         left_point = p, p = p->next);
  609. X        force_noanglegeom();
  610. X    canvas_locmove_proc = reshaping_line;
  611. X    break;
  612. X
  613. X    case T_BOX:
  614. X    case T_ARC_BOX:
  615. X    case T_EPS_BOX:
  616. X    if (right_point->next == NULL) {    /* point 4 */
  617. X        fix_x = cur_l->points->next->x;
  618. X        fix_y = cur_l->points->next->y;
  619. X    } else {
  620. X        fix_x = right_point->next->x;
  621. X        fix_y = right_point->next->y;
  622. X    }
  623. X    draw_line(cur_l, ERASE);
  624. X
  625. X    if (constrained) {
  626. X        double        dx, dy, l;
  627. X
  628. X        dx = cur_x - fix_x;
  629. X        dy = cur_y - fix_y;
  630. X        l = sqrt(dx * dx + dy * dy);
  631. X        cosa = fabs(dx / l);
  632. X        sina = fabs(dy / l);
  633. X    }
  634. X
  635. X        force_noanglegeom();
  636. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  637. X    canvas_locmove_proc = constrained_resizing_box;
  638. X    canvas_leftbut_proc = fix_box;
  639. X    canvas_rightbut_proc = cancel_box;
  640. X    return;
  641. X
  642. X    case T_POLYLINE:
  643. X    if (left_point != NULL) {
  644. X        if (left_point == cur_l->points) {
  645. X        if (cur_l->back_arrow)    /* backward arrow  */
  646. X            draw_arrow(cur_x, cur_y,
  647. X                   left_point->x, left_point->y,
  648. X                   cur_l->back_arrow, ERASE,
  649. X                   cur_l->color);
  650. X        }
  651. X    } else if (cur_l->back_arrow)    /* backward arrow  */
  652. X        draw_arrow(right_point->x, right_point->y,
  653. X               cur_x, cur_y, cur_l->back_arrow, ERASE,
  654. X               cur_l->color);
  655. X    if (right_point != NULL) {
  656. X        if (cur_l->for_arrow && right_point->next == NULL)
  657. X        draw_arrow(cur_x, cur_y, right_point->x, right_point->y,
  658. X               cur_l->for_arrow, ERASE,
  659. X               cur_l->color);
  660. X    } else if (cur_l->for_arrow)    /* f arrow */
  661. X        draw_arrow(left_point->x, left_point->y,
  662. X               cur_x, cur_y, cur_l->for_arrow, ERASE,
  663. X               cur_l->color);
  664. X    if (left_point == NULL || right_point == NULL) {
  665. X        if (left_point != NULL) {
  666. X        fix_x = left_point->x;
  667. X        fix_y = left_point->y;
  668. X        } else if (right_point != NULL) {
  669. X        fix_x = right_point->x;
  670. X        fix_y = right_point->y;
  671. X        }
  672. X            if (latexline_mode || latexarrow_mode) {
  673. X                canvas_locmove_proc = latex_line;
  674. X        cur_latexcursor = crosshair_cursor;
  675. X            } else if (mountain_mode || manhattan_mode) {
  676. X                canvas_locmove_proc = constrainedangle_line;
  677. X            } else {
  678. X        /* freehand line */
  679. X        canvas_locmove_proc = reshaping_line;
  680. X        }
  681. X    } else {
  682. X        /* linelink, always freehand */
  683. X            force_noanglegeom();
  684. X        canvas_locmove_proc = reshaping_line;
  685. X    }
  686. X    break;
  687. X    }
  688. X    elastic_linelink();
  689. X    canvas_leftbut_proc = fix_movedlinepoint;
  690. X    canvas_rightbut_proc = cancel_movedlinepoint;
  691. X}
  692. X
  693. Xstatic
  694. Xcancel_box()
  695. X{
  696. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  697. X    draw_line(cur_l, PAINT);
  698. X    toggle_linemarker(cur_l);
  699. X    wrapup_movepoint();
  700. X}
  701. X
  702. Xstatic
  703. Xfix_box(x, y)
  704. X    int            x, y;
  705. X{
  706. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  707. X    adjust_box_pos(x, y, from_x, from_y, &x, &y);
  708. X    new_l = copy_line(cur_l);
  709. X    draw_line(cur_l, ERASE);
  710. X    if (new_l->type == T_EPS_BOX) {
  711. X    if (signof(fix_x - from_x) != signof(fix_x - x))
  712. X        new_l->eps->flipped = 1 - new_l->eps->flipped;
  713. X    if (signof(fix_y - from_y) != signof(fix_y - y))
  714. X        new_l->eps->flipped = 1 - new_l->eps->flipped;
  715. X    }
  716. X    assign_newboxpoint(new_l, fix_x, fix_y, x, y);
  717. X    change_line(cur_l, new_l);
  718. X    draw_line(new_l, PAINT);
  719. X    toggle_linemarker(new_l);
  720. X    wrapup_movepoint();
  721. X}
  722. X
  723. Xstatic
  724. Xassign_newboxpoint(b, x1, y1, x2, y2)
  725. X    F_line       *b;
  726. X    int            x1, y1, x2, y2;
  727. X{
  728. X    F_point       *p;
  729. X
  730. X    p = b->points;
  731. X    if (p->x != x1)
  732. X    p->x = x2;
  733. X    if (p->y != y1)
  734. X    p->y = y2;
  735. X    p = p->next;
  736. X    if (p->x != x1)
  737. X    p->x = x2;
  738. X    if (p->y != y1)
  739. X    p->y = y2;
  740. X    p = p->next;
  741. X    if (p->x != x1)
  742. X    p->x = x2;
  743. X    if (p->y != y1)
  744. X    p->y = y2;
  745. X    p = p->next;
  746. X    if (p->x != x1)
  747. X    p->x = x2;
  748. X    if (p->y != y1)
  749. X    p->y = y2;
  750. X    p = p->next;
  751. X    if (p->x != x1)
  752. X    p->x = x2;
  753. X    if (p->y != y1)
  754. X    p->y = y2;
  755. X}
  756. X
  757. Xstatic
  758. Xcancel_movedlinepoint()
  759. X{
  760. X    elastic_linelink();
  761. X    toggle_linemarker(cur_l);
  762. X    wrapup_movepoint();
  763. X}
  764. X
  765. Xstatic
  766. Xfix_movedlinepoint(x, y)
  767. X    int            x, y;
  768. X{
  769. X    (*canvas_locmove_proc) (x, y);
  770. X    elastic_linelink();
  771. X    if (cur_latexcursor != crosshair_cursor)
  772. X    set_temp_cursor(crosshair_cursor);
  773. X    /* make a copy of the original and save as unchanged object */
  774. X    old_l = copy_line(cur_l);
  775. X    clean_up();
  776. X    set_latestline(old_l);
  777. X    set_action_object(F_CHANGE, O_POLYLINE);
  778. X    old_l->next = cur_l;
  779. X    /* now change the original to become the new object */
  780. X    relocate_linepoint(cur_l, cur_x, cur_y, moved_point, left_point);
  781. X    toggle_linemarker(cur_l);
  782. X    wrapup_movepoint();
  783. X}
  784. X
  785. Xstatic
  786. Xrelocate_linepoint(line, x, y, moved_point, left_point)
  787. X    F_line       *line;
  788. X    int            x, y;
  789. X    F_point       *moved_point, *left_point;
  790. X{
  791. X    draw_line(line, ERASE);
  792. X    if (line->type == T_POLYGON)
  793. X    if (line->points == moved_point) {
  794. X        left_point->next->x = x;
  795. X        left_point->next->y = y;
  796. X    }
  797. X    moved_point->x = x;
  798. X    moved_point->y = y;
  799. X    set_modifiedflag();
  800. X    draw_line(line, PAINT);
  801. X}
  802. END_OF_FILE
  803. if test 19377 -ne `wc -c <'e_movept.c'`; then
  804.     echo shar: \"'e_movept.c'\" unpacked with wrong size!
  805. fi
  806. # end of 'e_movept.c'
  807. fi
  808. if test -f 'u_list.c' -a "${1}" != "-c" ; then 
  809.   echo shar: Will not clobber existing file \"'u_list.c'\"
  810. else
  811. echo shar: Extracting \"'u_list.c'\" \(17965 characters\)
  812. sed "s/^X//" >'u_list.c' <<'END_OF_FILE'
  813. X/*
  814. X * FIG : Facility for Interactive Generation of figures
  815. X * Copyright (c) 1985 by Supoj Sutanthavibul
  816. X *
  817. X * "Permission to use, copy, modify, distribute, and sell this software and its
  818. X * documentation for any purpose is hereby granted without fee, provided that
  819. X * the above copyright notice appear in all copies and that both the copyright
  820. X * notice and this permission notice appear in supporting documentation. 
  821. X * No representations are made about the suitability of this software for 
  822. X * any purpose.  It is provided "as is" without express or implied warranty."
  823. X */
  824. X
  825. X#include "fig.h"
  826. X#include "mode.h"
  827. X#include "resources.h"
  828. X#include "object.h"
  829. X#include "paintop.h"
  830. X#include "u_create.h"
  831. X#include "u_list.h"
  832. X#include "u_elastic.h"
  833. X#include "u_undo.h"
  834. X
  835. Xvoid
  836. Xlist_delete_arc(arc_list, arc)
  837. X    F_arc      **arc_list, *arc;
  838. X{
  839. X    F_arc       *a, *aa;
  840. X
  841. X    if (*arc_list == NULL)
  842. X    return;
  843. X    if (arc == NULL)
  844. X    return;
  845. X
  846. X    for (a = aa = *arc_list; aa != NULL; a = aa, aa = aa->next) {
  847. X    if (aa == arc) {
  848. X        if (aa == *arc_list)
  849. X        *arc_list = (*arc_list)->next;
  850. X        else
  851. X        a->next = aa->next;
  852. X        break;
  853. X    }
  854. X    }
  855. X    arc->next = NULL;
  856. X}
  857. X
  858. Xvoid
  859. Xlist_delete_ellipse(ellipse_list, ellipse)
  860. X    F_ellipse      **ellipse_list, *ellipse;
  861. X{
  862. X    F_ellipse       *q, *r;
  863. X
  864. X    if (*ellipse_list == NULL)
  865. X    return;
  866. X    if (ellipse == NULL)
  867. X    return;
  868. X
  869. X    for (q = r = *ellipse_list; r != NULL; q = r, r = r->next) {
  870. X    if (r == ellipse) {
  871. X        if (r == *ellipse_list)
  872. X        *ellipse_list = (*ellipse_list)->next;
  873. X        else
  874. X        q->next = r->next;
  875. X        break;
  876. X    }
  877. X    }
  878. X    ellipse->next = NULL;
  879. X}
  880. X
  881. Xvoid
  882. Xlist_delete_line(line_list, line)
  883. X    F_line       *line, **line_list;
  884. X{
  885. X    F_line       *q, *r;
  886. X
  887. X    if (*line_list == NULL)
  888. X    return;
  889. X    if (line == NULL)
  890. X    return;
  891. X
  892. X    for (q = r = *line_list; r != NULL; q = r, r = r->next) {
  893. X    if (r == line) {
  894. X        if (r == *line_list)
  895. X        *line_list = (*line_list)->next;
  896. X        else
  897. X        q->next = r->next;
  898. X        break;
  899. X    }
  900. X    }
  901. X    line->next = NULL;
  902. X}
  903. X
  904. Xvoid
  905. Xlist_delete_spline(spline_list, spline)
  906. X    F_spline      **spline_list, *spline;
  907. X{
  908. X    F_spline       *q, *r;
  909. X
  910. X    if (*spline_list == NULL)
  911. X    return;
  912. X    if (spline == NULL)
  913. X    return;
  914. X
  915. X    for (q = r = *spline_list; r != NULL; q = r, r = r->next) {
  916. X    if (r == spline) {
  917. X        if (r == *spline_list)
  918. X        *spline_list = (*spline_list)->next;
  919. X        else
  920. X        q->next = r->next;
  921. X        break;
  922. X    }
  923. X    }
  924. X    spline->next = NULL;
  925. X}
  926. X
  927. Xvoid
  928. Xlist_delete_text(text_list, text)
  929. X    F_text      **text_list, *text;
  930. X{
  931. X    F_text       *q, *r;
  932. X
  933. X    if (*text_list == NULL)
  934. X    return;
  935. X    if (text == NULL)
  936. X    return;
  937. X
  938. X    for (q = r = *text_list; r != NULL; q = r, r = r->next)
  939. X    if (r == text) {
  940. X        if (r == *text_list)
  941. X        *text_list = text->next;
  942. X        else
  943. X        q->next = text->next;
  944. X        break;
  945. X    }
  946. X    text->next = NULL;
  947. X}
  948. X
  949. Xvoid
  950. Xlist_delete_compound(list, compound)
  951. X    F_compound      **list, *compound;
  952. X{
  953. X    F_compound       *c, *cc;
  954. X
  955. X    if (*list == NULL)
  956. X    return;
  957. X    if (compound == NULL)
  958. X    return;
  959. X
  960. X    for (cc = c = *list; c != NULL; cc = c, c = c->next) {
  961. X    if (c == compound) {
  962. X        if (c == *list)
  963. X        *list = (*list)->next;
  964. X        else
  965. X        cc->next = c->next;
  966. X        break;
  967. X    }
  968. X    }
  969. X    compound->next = NULL;
  970. X}
  971. X
  972. Xvoid
  973. Xlist_add_arc(arc_list, a)
  974. X    F_arc      **arc_list, *a;
  975. X{
  976. X    F_arc       *aa;
  977. X
  978. X    a->next = NULL;
  979. X    if ((aa = last_arc(*arc_list)) == NULL)
  980. X    *arc_list = a;
  981. X    else
  982. X    aa->next = a;
  983. X}
  984. X
  985. Xvoid
  986. Xlist_add_ellipse(ellipse_list, e)
  987. X    F_ellipse      **ellipse_list, *e;
  988. X{
  989. X    F_ellipse       *ee;
  990. X
  991. X    e->next = NULL;
  992. X    if ((ee = last_ellipse(*ellipse_list)) == NULL)
  993. X    *ellipse_list = e;
  994. X    else
  995. X    ee->next = e;
  996. X}
  997. X
  998. Xvoid
  999. Xlist_add_line(line_list, l)
  1000. X    F_line      **line_list, *l;
  1001. X{
  1002. X    F_line       *ll;
  1003. X
  1004. X    l->next = NULL;
  1005. X    if ((ll = last_line(*line_list)) == NULL)
  1006. X    *line_list = l;
  1007. X    else
  1008. X    ll->next = l;
  1009. X}
  1010. X
  1011. Xvoid
  1012. Xlist_add_spline(spline_list, s)
  1013. X    F_spline      **spline_list, *s;
  1014. X{
  1015. X    F_spline       *ss;
  1016. X
  1017. X    s->next = NULL;
  1018. X    if ((ss = last_spline(*spline_list)) == NULL)
  1019. X    *spline_list = s;
  1020. X    else
  1021. X    ss->next = s;
  1022. X}
  1023. X
  1024. Xvoid
  1025. Xlist_add_text(text_list, t)
  1026. X    F_text      **text_list, *t;
  1027. X{
  1028. X    F_text       *tt;
  1029. X
  1030. X    t->next = NULL;
  1031. X    if ((tt = last_text(*text_list)) == NULL)
  1032. X    *text_list = t;
  1033. X    else
  1034. X    tt->next = t;
  1035. X}
  1036. X
  1037. Xvoid
  1038. Xlist_add_compound(list, c)
  1039. X    F_compound      **list, *c;
  1040. X{
  1041. X    F_compound       *cc;
  1042. X
  1043. X    c->next = NULL;
  1044. X    if ((cc = last_compound(*list)) == NULL)
  1045. X    *list = c;
  1046. X    else
  1047. X    cc->next = c;
  1048. X}
  1049. X
  1050. Xvoid
  1051. Xdelete_line(old_l)
  1052. X    F_line       *old_l;
  1053. X{
  1054. X    list_delete_line(&objects.lines, old_l);
  1055. X    clean_up();
  1056. X    set_latestline(old_l);
  1057. X    set_action_object(F_DELETE, O_POLYLINE);
  1058. X    set_modifiedflag();
  1059. X}
  1060. X
  1061. Xvoid
  1062. Xdelete_arc(old_a)
  1063. X    F_arc       *old_a;
  1064. X{
  1065. X    list_delete_arc(&objects.arcs, old_a);
  1066. X    clean_up();
  1067. X    set_latestarc(old_a);
  1068. X    set_action_object(F_DELETE, O_ARC);
  1069. X    set_modifiedflag();
  1070. X}
  1071. X
  1072. Xvoid
  1073. Xdelete_ellipse(old_e)
  1074. X    F_ellipse       *old_e;
  1075. X{
  1076. X    list_delete_ellipse(&objects.ellipses, old_e);
  1077. X    clean_up();
  1078. X    set_latestellipse(old_e);
  1079. X    set_action_object(F_DELETE, O_ELLIPSE);
  1080. X    set_modifiedflag();
  1081. X}
  1082. X
  1083. Xvoid
  1084. Xdelete_text(old_t)
  1085. X    F_text       *old_t;
  1086. X{
  1087. X    list_delete_text(&objects.texts, old_t);
  1088. X    clean_up();
  1089. X    set_latesttext(old_t);
  1090. X    set_action_object(F_DELETE, O_TEXT);
  1091. X    set_modifiedflag();
  1092. X}
  1093. X
  1094. Xvoid
  1095. Xdelete_spline(old_s)
  1096. X    F_spline       *old_s;
  1097. X{
  1098. X    list_delete_spline(&objects.splines, old_s);
  1099. X    clean_up();
  1100. X    set_latestspline(old_s);
  1101. X    set_action_object(F_DELETE, O_SPLINE);
  1102. X    set_modifiedflag();
  1103. X}
  1104. X
  1105. Xvoid
  1106. Xdelete_compound(old_c)
  1107. X    F_compound       *old_c;
  1108. X{
  1109. X    list_delete_compound(&objects.compounds, old_c);
  1110. X    clean_up();
  1111. X    set_latestcompound(old_c);
  1112. X    set_action_object(F_DELETE, O_COMPOUND);
  1113. X    set_modifiedflag();
  1114. X}
  1115. X
  1116. Xvoid
  1117. Xadd_line(new_l)
  1118. X    F_line       *new_l;
  1119. X{
  1120. X    list_add_line(&objects.lines, new_l);
  1121. X    clean_up();
  1122. X    set_latestline(new_l);
  1123. X    set_action_object(F_ADD, O_POLYLINE);
  1124. X    set_modifiedflag();
  1125. X}
  1126. X
  1127. Xvoid
  1128. Xadd_arc(new_a)
  1129. X    F_arc       *new_a;
  1130. X{
  1131. X    list_add_arc(&objects.arcs, new_a);
  1132. X    clean_up();
  1133. X    set_latestarc(new_a);
  1134. X    set_action_object(F_ADD, O_ARC);
  1135. X    set_modifiedflag();
  1136. X}
  1137. X
  1138. Xvoid
  1139. Xadd_ellipse(new_e)
  1140. X    F_ellipse       *new_e;
  1141. X{
  1142. X    list_add_ellipse(&objects.ellipses, new_e);
  1143. X    clean_up();
  1144. X    set_latestellipse(new_e);
  1145. X    set_action_object(F_ADD, O_ELLIPSE);
  1146. X    set_modifiedflag();
  1147. X}
  1148. X
  1149. Xvoid
  1150. Xadd_text(new_t)
  1151. X    F_text       *new_t;
  1152. X{
  1153. X    list_add_text(&objects.texts, new_t);
  1154. X    clean_up();
  1155. X    set_latesttext(new_t);
  1156. X    set_action_object(F_ADD, O_TEXT);
  1157. X    set_modifiedflag();
  1158. X}
  1159. X
  1160. Xvoid
  1161. Xadd_spline(new_s)
  1162. X    F_spline       *new_s;
  1163. X{
  1164. X    list_add_spline(&objects.splines, new_s);
  1165. X    clean_up();
  1166. X    set_latestspline(new_s);
  1167. X    set_action_object(F_ADD, O_SPLINE);
  1168. X    set_modifiedflag();
  1169. X}
  1170. X
  1171. Xvoid
  1172. Xadd_compound(new_c)
  1173. X    F_compound       *new_c;
  1174. X{
  1175. X    list_add_compound(&objects.compounds, new_c);
  1176. X    clean_up();
  1177. X    set_latestcompound(new_c);
  1178. X    set_action_object(F_ADD, O_COMPOUND);
  1179. X    set_modifiedflag();
  1180. X}
  1181. X
  1182. X
  1183. Xvoid
  1184. Xchange_line(old_l, new_l)
  1185. X    F_line       *old_l, *new_l;
  1186. X{
  1187. X    list_delete_line(&objects.lines, old_l);
  1188. X    list_add_line(&objects.lines, new_l);
  1189. X    clean_up();
  1190. X    old_l->next = new_l;
  1191. X    set_latestline(old_l);
  1192. X    set_action_object(F_CHANGE, O_POLYLINE);
  1193. X    set_modifiedflag();
  1194. X}
  1195. X
  1196. Xvoid
  1197. Xchange_arc(old_a, new_a)
  1198. X    F_arc       *old_a, *new_a;
  1199. X{
  1200. X    list_delete_arc(&objects.arcs, old_a);
  1201. X    list_add_arc(&objects.arcs, new_a);
  1202. X    clean_up();
  1203. X    old_a->next = new_a;
  1204. X    set_latestarc(old_a);
  1205. X    set_action_object(F_CHANGE, O_ARC);
  1206. X    set_modifiedflag();
  1207. X}
  1208. X
  1209. Xvoid
  1210. Xchange_ellipse(old_e, new_e)
  1211. X    F_ellipse       *old_e, *new_e;
  1212. X{
  1213. X    list_delete_ellipse(&objects.ellipses, old_e);
  1214. X    list_add_ellipse(&objects.ellipses, new_e);
  1215. X    clean_up();
  1216. X    old_e->next = new_e;
  1217. X    set_latestellipse(old_e);
  1218. X    set_action_object(F_CHANGE, O_ELLIPSE);
  1219. X    set_modifiedflag();
  1220. X}
  1221. X
  1222. Xvoid
  1223. Xchange_text(old_t, new_t)
  1224. X    F_text       *old_t, *new_t;
  1225. X{
  1226. X    list_delete_text(&objects.texts, old_t);
  1227. X    list_add_text(&objects.texts, new_t);
  1228. X    clean_up();
  1229. X    old_t->next = new_t;
  1230. X    set_latesttext(old_t);
  1231. X    set_action_object(F_CHANGE, O_TEXT);
  1232. X    set_modifiedflag();
  1233. X}
  1234. X
  1235. Xvoid
  1236. Xchange_spline(old_s, new_s)
  1237. X    F_spline       *old_s, *new_s;
  1238. X{
  1239. X    list_delete_spline(&objects.splines, old_s);
  1240. X    list_add_spline(&objects.splines, new_s);
  1241. X    clean_up();
  1242. X    old_s->next = new_s;
  1243. X    set_latestspline(old_s);
  1244. X    set_action_object(F_CHANGE, O_SPLINE);
  1245. X    set_modifiedflag();
  1246. X}
  1247. X
  1248. Xvoid
  1249. Xchange_compound(old_c, new_c)
  1250. X    F_compound       *old_c, *new_c;
  1251. X{
  1252. X    list_delete_compound(&objects.compounds, old_c);
  1253. X    list_add_compound(&objects.compounds, new_c);
  1254. X    clean_up();
  1255. X    old_c->next = new_c;
  1256. X    set_latestcompound(old_c);
  1257. X    set_action_object(F_CHANGE, O_COMPOUND);
  1258. X    set_modifiedflag();
  1259. X}
  1260. X
  1261. Xtail(ob, tails)
  1262. X    F_compound       *ob, *tails;
  1263. X{
  1264. X    F_arc       *a;
  1265. X    F_compound       *c;
  1266. X    F_ellipse       *e;
  1267. X    F_line       *l;
  1268. X    F_spline       *s;
  1269. X    F_text       *t;
  1270. X
  1271. X    if (NULL != (a = ob->arcs))
  1272. X    for (; a->next != NULL; a = a->next);
  1273. X    if (NULL != (c = ob->compounds))
  1274. X    for (; c->next != NULL; c = c->next);
  1275. X    if (NULL != (e = ob->ellipses))
  1276. X    for (; e->next != NULL; e = e->next);
  1277. X    if (NULL != (l = ob->lines))
  1278. X    for (; l->next != NULL; l = l->next);
  1279. X    if (NULL != (s = ob->splines))
  1280. X    for (; s->next != NULL; s = s->next);
  1281. X    if (NULL != (t = ob->texts))
  1282. X    for (; t->next != NULL; t = t->next);
  1283. X
  1284. X    tails->arcs = a;
  1285. X    tails->compounds = c;
  1286. X    tails->ellipses = e;
  1287. X    tails->lines = l;
  1288. X    tails->splines = s;
  1289. X    tails->texts = t;
  1290. X}
  1291. X
  1292. X/*
  1293. X * Make pointers in tails point to the last element of each list of l1 and
  1294. X * Append the lists in l2 after those in l1. The tails pointers must be
  1295. X * defined prior to calling append.
  1296. X */
  1297. Xappend_objects(l1, l2, tails)
  1298. X    F_compound       *l1, *l2, *tails;
  1299. X{
  1300. X    if (tails->arcs)
  1301. X    tails->arcs->next = l2->arcs;
  1302. X    else
  1303. X    l1->arcs = l2->arcs;
  1304. X    if (tails->compounds)
  1305. X    tails->compounds->next = l2->compounds;
  1306. X    else
  1307. X    l1->compounds = l2->compounds;
  1308. X    if (tails->ellipses)
  1309. X    tails->ellipses->next = l2->ellipses;
  1310. X    else
  1311. X    l1->ellipses = l2->ellipses;
  1312. X    if (tails->lines)
  1313. X    tails->lines->next = l2->lines;
  1314. X    else
  1315. X    l1->lines = l2->lines;
  1316. X    if (tails->splines)
  1317. X    tails->splines->next = l2->splines;
  1318. X    else
  1319. X    l1->splines = l2->splines;
  1320. X    if (tails->texts)
  1321. X    tails->texts->next = l2->texts;
  1322. X    else
  1323. X    l1->texts = l2->texts;
  1324. X}
  1325. X
  1326. X/* Cut is the dual of append. */
  1327. X
  1328. Xcut_objects(objects, tails)
  1329. X    F_compound       *objects, *tails;
  1330. X{
  1331. X    if (tails->arcs)
  1332. X    tails->arcs->next = NULL;
  1333. X    else
  1334. X    objects->arcs = NULL;
  1335. X    if (tails->compounds)
  1336. X    tails->compounds->next = NULL;
  1337. X    else
  1338. X    objects->compounds = NULL;
  1339. X    if (tails->ellipses)
  1340. X    tails->ellipses->next = NULL;
  1341. X    else
  1342. X    objects->ellipses = NULL;
  1343. X    if (tails->lines)
  1344. X    tails->lines->next = NULL;
  1345. X    else
  1346. X    objects->lines = NULL;
  1347. X    if (tails->splines)
  1348. X    tails->splines->next = NULL;
  1349. X    else
  1350. X    objects->splines = NULL;
  1351. X    if (tails->texts)
  1352. X    tails->texts->next = NULL;
  1353. X    else
  1354. X    objects->texts = NULL;
  1355. X}
  1356. X
  1357. Xappend_point(x, y, point)
  1358. X    int            x, y;
  1359. X    F_point      **point;
  1360. X{
  1361. X    F_point       *p;
  1362. X
  1363. X    if ((p = create_point()) == NULL)
  1364. X    return;
  1365. X
  1366. X    p->x = x;
  1367. X    p->y = y;
  1368. X    p->next = NULL;
  1369. X    (*point)->next = p;
  1370. X    *point = p;
  1371. X}
  1372. X
  1373. Xnum_points(points)
  1374. X    F_point       *points;
  1375. X{
  1376. X    int            n;
  1377. X    F_point       *p;
  1378. X
  1379. X    for (p = points, n = 0; p != NULL; p = p->next, n++);
  1380. X    return (n);
  1381. X}
  1382. X
  1383. XF_text           *
  1384. Xlast_text(list)
  1385. X    F_text       *list;
  1386. X{
  1387. X    F_text       *tt;
  1388. X
  1389. X    if (list == NULL)
  1390. X    return NULL;
  1391. X
  1392. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1393. X    return tt;
  1394. X}
  1395. X
  1396. XF_line           *
  1397. Xlast_line(list)
  1398. X    F_line       *list;
  1399. X{
  1400. X    F_line       *ll;
  1401. X
  1402. X    if (list == NULL)
  1403. X    return NULL;
  1404. X
  1405. X    for (ll = list; ll->next != NULL; ll = ll->next);
  1406. X    return ll;
  1407. X}
  1408. X
  1409. XF_spline       *
  1410. Xlast_spline(list)
  1411. X    F_spline       *list;
  1412. X{
  1413. X    F_spline       *ss;
  1414. X
  1415. X    if (list == NULL)
  1416. X    return NULL;
  1417. X
  1418. X    for (ss = list; ss->next != NULL; ss = ss->next);
  1419. X    return ss;
  1420. X}
  1421. X
  1422. XF_arc           *
  1423. Xlast_arc(list)
  1424. X    F_arc       *list;
  1425. X{
  1426. X    F_arc       *tt;
  1427. X
  1428. X    if (list == NULL)
  1429. X    return NULL;
  1430. X
  1431. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1432. X    return tt;
  1433. X}
  1434. X
  1435. XF_ellipse      *
  1436. Xlast_ellipse(list)
  1437. X    F_ellipse       *list;
  1438. X{
  1439. X    F_ellipse       *tt;
  1440. X
  1441. X    if (list == NULL)
  1442. X    return NULL;
  1443. X
  1444. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1445. X    return tt;
  1446. X}
  1447. X
  1448. XF_compound     *
  1449. Xlast_compound(list)
  1450. X    F_compound       *list;
  1451. X{
  1452. X    F_compound       *tt;
  1453. X
  1454. X    if (list == NULL)
  1455. X    return NULL;
  1456. X
  1457. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1458. X    return tt;
  1459. X}
  1460. X
  1461. XF_point           *
  1462. Xlast_point(list)
  1463. X    F_point       *list;
  1464. X{
  1465. X    F_point       *tt;
  1466. X
  1467. X    if (list == NULL)
  1468. X    return NULL;
  1469. X
  1470. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1471. X    return tt;
  1472. X}
  1473. X
  1474. XF_arc           *
  1475. Xprev_arc(list, arc)
  1476. X    F_arc       *list, *arc;
  1477. X{
  1478. X    F_arc       *csr;
  1479. X
  1480. X    if (list == arc)
  1481. X    return NULL;
  1482. X
  1483. X    for (csr = list; csr->next != arc; csr = csr->next);
  1484. X    return csr;
  1485. X}
  1486. X
  1487. XF_compound     *
  1488. Xprev_compound(list, compound)
  1489. X    F_compound       *list, *compound;
  1490. X{
  1491. X    F_compound       *csr;
  1492. X
  1493. X    if (list == compound)
  1494. X    return NULL;
  1495. X
  1496. X    for (csr = list; csr->next != compound; csr = csr->next);
  1497. X    return csr;
  1498. X}
  1499. X
  1500. XF_ellipse      *
  1501. Xprev_ellipse(list, ellipse)
  1502. X    F_ellipse       *list, *ellipse;
  1503. X{
  1504. X    F_ellipse       *csr;
  1505. X
  1506. X    if (list == ellipse)
  1507. X    return NULL;
  1508. X
  1509. X    for (csr = list; csr->next != ellipse; csr = csr->next);
  1510. X    return csr;
  1511. X}
  1512. X
  1513. XF_line           *
  1514. Xprev_line(list, line)
  1515. X    F_line       *list, *line;
  1516. X{
  1517. X    F_line       *csr;
  1518. X
  1519. X    if (list == line)
  1520. X    return NULL;
  1521. X
  1522. X    for (csr = list; csr->next != line; csr = csr->next);
  1523. X    return csr;
  1524. X}
  1525. X
  1526. XF_spline       *
  1527. Xprev_spline(list, spline)
  1528. X    F_spline       *list, *spline;
  1529. X{
  1530. X    F_spline       *csr;
  1531. X
  1532. X    if (list == spline)
  1533. X    return NULL;
  1534. X
  1535. X    for (csr = list; csr->next != spline; csr = csr->next);
  1536. X    return csr;
  1537. X}
  1538. X
  1539. XF_text           *
  1540. Xprev_text(list, text)
  1541. X    F_text       *list, *text;
  1542. X{
  1543. X    F_text       *csr;
  1544. X
  1545. X    if (list == text)
  1546. X    return NULL;
  1547. X
  1548. X    for (csr = list; csr->next != text; csr = csr->next);
  1549. X    return csr;
  1550. X}
  1551. X
  1552. XF_point           *
  1553. Xprev_point(list, point)
  1554. X    F_point       *list, *point;
  1555. X{
  1556. X    F_point       *csr;
  1557. X
  1558. X    if (list == point)
  1559. X    return NULL;
  1560. X
  1561. X    for (csr = list; csr->next != point; csr = csr->next);
  1562. X    return csr;
  1563. X}
  1564. X
  1565. Xint
  1566. Xobject_count(list)
  1567. X    F_compound       *list;
  1568. X{
  1569. X    register int    cnt;
  1570. X    F_arc       *a;
  1571. X    F_text       *t;
  1572. X    F_compound       *c;
  1573. X    F_ellipse       *e;
  1574. X    F_line       *l;
  1575. X    F_spline       *s;
  1576. X
  1577. X    cnt = 0;
  1578. X    for (a = list->arcs; a != NULL; a = a->next, cnt++);
  1579. X    for (t = list->texts; t != NULL; t = t->next, cnt++);
  1580. X    for (c = list->compounds; c != NULL; c = c->next, cnt++);
  1581. X    for (e = list->ellipses; e != NULL; e = e->next, cnt++);
  1582. X    for (l = list->lines; l != NULL; l = l->next, cnt++);
  1583. X    for (s = list->splines; s != NULL; s = s->next, cnt++);
  1584. X    return (cnt);
  1585. X}
  1586. X
  1587. Xset_tags(list, tag)
  1588. X    F_compound       *list;
  1589. X    int            tag;
  1590. X{
  1591. X    F_arc       *a;
  1592. X    F_text       *t;
  1593. X    F_compound       *c;
  1594. X    F_ellipse       *e;
  1595. X    F_line       *l;
  1596. X    F_spline       *s;
  1597. X
  1598. X    for (a = list->arcs; a != NULL; a = a->next) {
  1599. X    mask_toggle_arcmarker(a);
  1600. X    a->tagged = tag;
  1601. X    mask_toggle_arcmarker(a);
  1602. X    }
  1603. X    for (t = list->texts; t != NULL; t = t->next) {
  1604. X    mask_toggle_textmarker(t);
  1605. X    t->tagged = tag;
  1606. X    mask_toggle_textmarker(t);
  1607. X    }
  1608. X    for (c = list->compounds; c != NULL; c = c->next) {
  1609. X    mask_toggle_compoundmarker(c);
  1610. X    c->tagged = tag;
  1611. X    mask_toggle_compoundmarker(c);
  1612. X    }
  1613. X    for (e = list->ellipses; e != NULL; e = e->next) {
  1614. X    mask_toggle_ellipsemarker(e);
  1615. X    e->tagged = tag;
  1616. X    mask_toggle_ellipsemarker(e);
  1617. X    }
  1618. X    for (l = list->lines; l != NULL; l = l->next) {
  1619. X    mask_toggle_linemarker(l);
  1620. X    l->tagged = tag;
  1621. X    mask_toggle_linemarker(l);
  1622. X    }
  1623. X    for (s = list->splines; s != NULL; s = s->next) {
  1624. X    mask_toggle_splinemarker(s);
  1625. X    s->tagged = tag;
  1626. X    mask_toggle_splinemarker(s);
  1627. X    }
  1628. X}
  1629. X
  1630. Xvoid
  1631. Xget_links(llx, lly, urx, ury)
  1632. X    int            llx, lly, urx, ury;
  1633. X{
  1634. X    F_line       *l;
  1635. X    F_point       *a;
  1636. X    F_linkinfo       *j, *k;
  1637. X
  1638. X    j = NULL;
  1639. X    for (l = objects.lines; l != NULL; l = l->next)
  1640. X    if (l->type == T_POLYLINE) {
  1641. X        a = l->points;
  1642. X        if (point_on_perim(a, llx, lly, urx, ury)) {
  1643. X        if ((k = new_link(l, a, a->next)) == NULL)
  1644. X            return;
  1645. X        if (j == NULL)
  1646. X            cur_links = k;
  1647. X        else
  1648. X            j->next = k;
  1649. X        j = k;
  1650. X        if (k->prevpt != NULL)
  1651. X            k->two_pts = (k->prevpt->next == NULL);
  1652. X        continue;
  1653. X        }
  1654. X        if (a->next == NULL)/* single point, no need to check further */
  1655. X        continue;
  1656. X        a = last_point(l->points);
  1657. X        if (point_on_perim(a, llx, lly, urx, ury)) {
  1658. X        if ((k = new_link(l, a, prev_point(l->points, a))) == NULL)
  1659. X            return;
  1660. X        if (j == NULL)
  1661. X            cur_links = k;
  1662. X        else
  1663. X            j->next = k;
  1664. X        j = k;
  1665. X        if (k->prevpt != NULL)
  1666. X            k->two_pts = (prev_point(l->points, k->prevpt) == NULL);
  1667. X        continue;
  1668. X        }
  1669. X    }
  1670. X}
  1671. X
  1672. X#define LINK_TOL 3
  1673. X
  1674. Xint
  1675. Xpoint_on_perim(p, llx, lly, urx, ury)
  1676. X    F_point       *p;
  1677. X    int            llx, lly, urx, ury;
  1678. X{
  1679. X    return ((abs(p->x - llx) <= LINK_TOL && p->y >= lly - LINK_TOL
  1680. X         && p->y <= ury + LINK_TOL) ||
  1681. X        (abs(p->x - urx) <= LINK_TOL && p->y >= lly - LINK_TOL
  1682. X         && p->y <= ury + LINK_TOL) ||
  1683. X        (abs(p->y - lly) <= LINK_TOL && p->x >= llx - LINK_TOL
  1684. X         && p->x <= urx + LINK_TOL) ||
  1685. X        (abs(p->y - ury) <= LINK_TOL && p->x >= llx - LINK_TOL
  1686. X         && p->x <= urx + LINK_TOL));
  1687. X}
  1688. X
  1689. Xvoid
  1690. Xadjust_links(mode, links, dx, dy, cx, cy, sx, sy, copying)
  1691. X    int            mode;
  1692. X    F_linkinfo       *links;
  1693. X    int        dx, dy;        /* delta */
  1694. X    int        cx, cy;        /* center of scale - NOT USED YET */
  1695. X    float    sx, sy;        /* scale factor - NOT USED YET */
  1696. X    int            copying;
  1697. X{
  1698. X    F_linkinfo       *k;
  1699. X    F_line       *l;
  1700. X
  1701. X    if (mode != SMART_OFF)
  1702. X    for (k = links; k != NULL; k = k->next) {
  1703. X        if (copying) {
  1704. X        l = copy_line(k->line);
  1705. X        list_delete_line(&objects.lines, k->line);
  1706. X        list_add_line(&saved_objects.lines, k->line);
  1707. X        list_add_line(&objects.lines, l);
  1708. X        } else {
  1709. X        mask_toggle_linemarker(k->line);
  1710. X        draw_line(k->line, ERASE);
  1711. X        }
  1712. X        if (mode == SMART_SLIDE && k->prevpt != NULL) {
  1713. X        if (k->endpt->x == k->prevpt->x)
  1714. X            k->prevpt->x += dx;
  1715. X        else
  1716. X            k->prevpt->y += dy;
  1717. X        }
  1718. X        k->endpt->x += dx;
  1719. X        k->endpt->y += dy;
  1720. X        draw_line(k->line, PAINT);
  1721. X        mask_toggle_linemarker(k->line);
  1722. X    }
  1723. X}
  1724. END_OF_FILE
  1725. if test 17965 -ne `wc -c <'u_list.c'`; then
  1726.     echo shar: \"'u_list.c'\" unpacked with wrong size!
  1727. fi
  1728. # end of 'u_list.c'
  1729. fi
  1730. if test -f 'u_search.c' -a "${1}" != "-c" ; then 
  1731.   echo shar: Will not clobber existing file \"'u_search.c'\"
  1732. else
  1733. echo shar: Extracting \"'u_search.c'\" \(19267 characters\)
  1734. sed "s/^X//" >'u_search.c' <<'END_OF_FILE'
  1735. X/*
  1736. X * FIG : Facility for Interactive Generation of figures
  1737. X * Copyright (c) 1985 by Supoj Sutanthavibul
  1738. X *
  1739. X * "Permission to use, copy, modify, distribute, and sell this software and its
  1740. X * documentation for any purpose is hereby granted without fee, provided that
  1741. X * the above copyright notice appear in all copies and that both the copyright
  1742. X * notice and this permission notice appear in supporting documentation. 
  1743. X * No representations are made about the suitability of this software for 
  1744. X * any purpose.  It is provided "as is" without express or implied warranty."
  1745. X */
  1746. X
  1747. X#include "fig.h"
  1748. X#include "resources.h"
  1749. X#include "object.h"
  1750. X#include "mode.h"
  1751. X#include "u_list.h"
  1752. X#include "w_zoom.h"
  1753. X
  1754. X#define TOLERANCE 3
  1755. X
  1756. Xstatic        (*manipulate) ();
  1757. Xstatic        (*handlerproc_left) ();
  1758. Xstatic        (*handlerproc_middle) ();
  1759. Xstatic        (*handlerproc_right) ();
  1760. Xstatic int    type;
  1761. Xstatic long    objectcount;
  1762. Xstatic long    n;
  1763. Xstatic int    csr_x, csr_y;
  1764. X
  1765. Xstatic F_point    point1, point2;
  1766. X
  1767. Xstatic F_arc   *a;
  1768. Xstatic F_ellipse *e;
  1769. Xstatic F_line  *l;
  1770. Xstatic F_spline *s;
  1771. Xstatic F_text  *t;
  1772. Xstatic F_compound *c;
  1773. X
  1774. Xchar
  1775. Xnext_arc_found(x, y, tolerance, px, py, shift)
  1776. X    int            x, y, tolerance, *px, *py;
  1777. X    int            shift;
  1778. X{                /* (px, py) is the control point on the
  1779. X                 * circumference of an arc which is the
  1780. X                 * closest to (x, y)                 */
  1781. X
  1782. X    int            i;
  1783. X
  1784. X    if (!arc_in_mask())
  1785. X    return (0);
  1786. X    if (a == NULL)
  1787. X    a = last_arc(objects.arcs);
  1788. X    else if (shift)
  1789. X    a = prev_arc(objects.arcs, a);
  1790. X
  1791. X    for (; a != NULL; a = prev_arc(objects.arcs, a), n++) {
  1792. X    for (i = 0; i < 3; i++)
  1793. X        if ((abs(a->point[i].x - x) <= tolerance) &&
  1794. X        (abs(a->point[i].y - y) <= tolerance)) {
  1795. X        *px = a->point[i].x;
  1796. X        *py = a->point[i].y;
  1797. X        return (1);
  1798. X        }
  1799. X    }
  1800. X    return (0);
  1801. X}
  1802. X
  1803. X
  1804. Xchar
  1805. Xnext_ellipse_found(x, y, tolerance, px, py, shift)
  1806. X    int            x, y, tolerance, *px, *py;
  1807. X    int            shift;
  1808. X{                /* (px, py) is the point on the circumference
  1809. X                 * of an ellipse which is the closest to (x,
  1810. X                 * y)                 */
  1811. X
  1812. X    int            a, b, dx, dy;
  1813. X    float        dis, r, tol;
  1814. X
  1815. X    if (!ellipse_in_mask())
  1816. X    return (0);
  1817. X    if (e == NULL)
  1818. X    e = last_ellipse(objects.ellipses);
  1819. X    else if (shift)
  1820. X    e = prev_ellipse(objects.ellipses, e);
  1821. X
  1822. X    tol = (float) tolerance;
  1823. X    for (; e != NULL; e = prev_ellipse(objects.ellipses, e), n++) {
  1824. X    dx = x - e->center.x;
  1825. X    dy = y - e->center.y;
  1826. X    a = e->radiuses.x;
  1827. X    b = e->radiuses.y;
  1828. X    /* prevent sqrt(0) core dumps */
  1829. X    if (dx == 0 && dy == 0)
  1830. X        dis = 0;        /* so we return below */
  1831. X    else
  1832. X        dis = sqrt((double) (dx * dx + dy * dy));
  1833. X    if (dis < tol) {
  1834. X        *px = e->center.x;
  1835. X        *py = e->center.y;
  1836. X        return (1);
  1837. X    }
  1838. X    if (abs(x - e->start.x) <= tolerance && abs(y - e->start.y) <= tolerance) {
  1839. X        *px = e->start.x;
  1840. X        *py = e->start.y;
  1841. X        return (1);
  1842. X    }
  1843. X    if (abs(x - e->end.x) <= tolerance && abs(y - e->end.y) <= tolerance) {
  1844. X        *px = e->end.x;
  1845. X        *py = e->end.y;
  1846. X        return (1);
  1847. X    }
  1848. X    if (a * dy == 0 && b * dx == 0)
  1849. X        r = 0;        /* prevent core dumps */
  1850. X    else
  1851. X        r = a * b * dis / sqrt((double) (1.0 * b * b * dx * dx + 1.0 * a * a * dy * dy));
  1852. X    if (fabs(dis - r) <= tol) {
  1853. X        *px = (int) (r * dx / dis + ((dx < 0) ? -.5 : .5)) + e->center.x;
  1854. X        *py = (int) (r * dy / dis + ((dy < 0) ? -.5 : .5)) + e->center.y;
  1855. X        return (1);
  1856. X    }
  1857. X    }
  1858. X    return (0);
  1859. X}
  1860. X
  1861. Xchar
  1862. Xnext_line_found(x, y, tolerance, px, py, shift)
  1863. X    int            x, y, tolerance, *px, *py, shift;
  1864. X{                /* return the pointer to lines object if the
  1865. X                 * search is successful otherwise return
  1866. X                 * NULL.  The value returned via (px, py) is
  1867. X                 * the closest point on the vector to point
  1868. X                 * (x, y)                     */
  1869. X
  1870. X    F_point       *point;
  1871. X    int            x1, y1, x2, y2;
  1872. X    float        tol2;
  1873. X
  1874. X    tol2 = (float) tolerance *tolerance;
  1875. X
  1876. X    if (!anyline_in_mask())
  1877. X    return (0);
  1878. X    if (l == NULL)
  1879. X    l = last_line(objects.lines);
  1880. X    else if (shift)
  1881. X    l = prev_line(objects.lines, l);
  1882. X
  1883. X    for (; l != NULL; l = prev_line(objects.lines, l))
  1884. X    if (validline_in_mask(l)) {
  1885. X        n++;
  1886. X        point = l->points;
  1887. X        x1 = point->x;
  1888. X        y1 = point->y;
  1889. X        if (abs(x - x1) <= tolerance && abs(y - y1) <= tolerance) {
  1890. X        *px = x1;
  1891. X        *py = y1;
  1892. X        return (1);
  1893. X        }
  1894. X        for (point = point->next; point != NULL; point = point->next) {
  1895. X        x2 = point->x;
  1896. X        y2 = point->y;
  1897. X        if (close_to_vector(x1, y1, x2, y2, x, y, tolerance, tol2,
  1898. X                    px, py))
  1899. X            return (1);
  1900. X        x1 = x2;
  1901. X        y1 = y2;
  1902. X        }
  1903. X    }
  1904. X    return (0);
  1905. X}
  1906. X
  1907. Xchar
  1908. Xnext_spline_found(x, y, tolerance, px, py, shift)
  1909. X    int            x, y, tolerance, *px, *py;
  1910. X    int            shift;
  1911. X{                /* return the pointer to lines object if the
  1912. X                 * search is successful otherwise return
  1913. X                 * NULL.  */
  1914. X
  1915. X    F_point       *point;
  1916. X    int            x1, y1, x2, y2;
  1917. X    float        tol2;
  1918. X
  1919. X    if (!anyspline_in_mask())
  1920. X    return (0);
  1921. X    if (s == NULL)
  1922. X    s = last_spline(objects.splines);
  1923. X    else if (shift)
  1924. X    s = prev_spline(objects.splines, s);
  1925. X
  1926. X    tol2 = (float) tolerance *tolerance;
  1927. X
  1928. X    for (; s != NULL; s = prev_spline(objects.splines, s))
  1929. X    if (validspline_in_mask(s)) {
  1930. X        n++;
  1931. X        point = s->points;
  1932. X        x1 = point->x;
  1933. X        y1 = point->y;
  1934. X        for (point = point->next; point != NULL; point = point->next) {
  1935. X        x2 = point->x;
  1936. X        y2 = point->y;
  1937. X        if (close_to_vector(x1, y1, x2, y2, x, y, tolerance, tol2,
  1938. X                    px, py))
  1939. X            return (1);
  1940. X        x1 = x2;
  1941. X        y1 = y2;
  1942. X        }
  1943. X    }
  1944. X    return (0);
  1945. X}
  1946. X
  1947. Xchar
  1948. Xnext_text_found(x, y, tolerance, px, py, shift)
  1949. X    int            x, y, tolerance, *px, *py;
  1950. X    int            shift;
  1951. X{
  1952. X    int            halflen, dx, dy;
  1953. X    int            txmin, txmax, tymin, tymax;
  1954. X
  1955. X    if (!anytext_in_mask())
  1956. X    return (0);
  1957. X    if (t == NULL)
  1958. X    t = last_text(objects.texts);
  1959. X    else if (shift)
  1960. X    t = prev_text(objects.texts, t);
  1961. X
  1962. X    for (; t != NULL; t = prev_text(objects.texts, t))
  1963. X    if (validtext_in_mask(t)) {
  1964. X        n++;
  1965. X        text_bound(t, &txmin, &tymin, &txmax, &tymax);
  1966. X        if (x >= txmin-tolerance && x <= txmax+tolerance &&
  1967. X            y >= tymin-tolerance && y <= tymax+tolerance) {
  1968. X            *px = x;
  1969. X            *py = y;
  1970. X            return (1);
  1971. X        }
  1972. X    }
  1973. X    return (0);
  1974. X}
  1975. X
  1976. Xint
  1977. Xnext_compound_found(x, y, tolerance, px, py, shift)
  1978. X    int            x, y, tolerance, *px, *py;
  1979. X    int            shift;
  1980. X{
  1981. X    float        tol2;
  1982. X
  1983. X    if (!compound_in_mask())
  1984. X    return (0);
  1985. X    if (c == NULL)
  1986. X    c = last_compound(objects.compounds);
  1987. X    else if (shift)
  1988. X    c = prev_compound(objects.compounds, c);
  1989. X
  1990. X    tol2 = tolerance * tolerance;
  1991. X
  1992. X    for (; c != NULL; c = prev_compound(objects.compounds, c), n++) {
  1993. X    if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->nwcorner.x,
  1994. X                c->secorner.y, x, y, tolerance, tol2, px, py))
  1995. X        return (1);
  1996. X    if (close_to_vector(c->secorner.x, c->secorner.y, c->nwcorner.x,
  1997. X                c->secorner.y, x, y, tolerance, tol2, px, py))
  1998. X        return (1);
  1999. X    if (close_to_vector(c->secorner.x, c->secorner.y, c->secorner.x,
  2000. X                c->nwcorner.y, x, y, tolerance, tol2, px, py))
  2001. X        return (1);
  2002. X    if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->secorner.x,
  2003. X                c->nwcorner.y, x, y, tolerance, tol2, px, py))
  2004. X        return (1);
  2005. X    }
  2006. X    return (0);
  2007. X}
  2008. X
  2009. Xshow_objecthighlight()
  2010. X{
  2011. X    if (highlighting)
  2012. X    return;
  2013. X    highlighting = 1;
  2014. X    toggle_objecthighlight();
  2015. X}
  2016. X
  2017. Xerase_objecthighlight()
  2018. X{
  2019. X    if (!highlighting)
  2020. X    return;
  2021. X    highlighting = 0;
  2022. X    toggle_objecthighlight();
  2023. X    if (type == -1) {
  2024. X    e = NULL;
  2025. X    type = O_ELLIPSE;
  2026. X    }
  2027. X}
  2028. X
  2029. Xtoggle_objecthighlight()
  2030. X{
  2031. X    switch (type) {
  2032. X    case O_ELLIPSE:
  2033. X    toggle_ellipsehighlight(e);
  2034. X    break;
  2035. X    case O_POLYLINE:
  2036. X    toggle_linehighlight(l);
  2037. X    break;
  2038. X    case O_SPLINE:
  2039. X    toggle_splinehighlight(s);
  2040. X    break;
  2041. X    case O_TEXT:
  2042. X    toggle_texthighlight(t);
  2043. X    break;
  2044. X    case O_ARC:
  2045. X    toggle_archighlight(a);
  2046. X    break;
  2047. X    case O_COMPOUND:
  2048. X    toggle_compoundhighlight(c);
  2049. X    break;
  2050. X    default:
  2051. X    toggle_csrhighlight(csr_x, csr_y);
  2052. X    }
  2053. X}
  2054. X
  2055. Xstatic void
  2056. Xinit_search()
  2057. X{
  2058. X    if (highlighting)
  2059. X    erase_objecthighlight();
  2060. X    else {
  2061. X    objectcount = 0;
  2062. X    if (ellipse_in_mask())
  2063. X        for (e = objects.ellipses; e != NULL; e = e->next)
  2064. X        objectcount++;
  2065. X    if (anyline_in_mask())
  2066. X        for (l = objects.lines; l != NULL; l = l->next)
  2067. X        if (validline_in_mask(l))
  2068. X            objectcount++;
  2069. X    if (anyspline_in_mask())
  2070. X        for (s = objects.splines; s != NULL; s = s->next)
  2071. X        if (validspline_in_mask(s))
  2072. X            objectcount++;
  2073. X    if (anytext_in_mask())
  2074. X        for (t = objects.texts; t != NULL; t = t->next)
  2075. X        if (validtext_in_mask(t))
  2076. X            objectcount++;
  2077. X    if (arc_in_mask())
  2078. X        for (a = objects.arcs; a != NULL; a = a->next)
  2079. X        objectcount++;
  2080. X    if (compound_in_mask())
  2081. X        for (c = objects.compounds; c != NULL; c = c->next)
  2082. X        objectcount++;
  2083. X    e = NULL;
  2084. X    type = O_ELLIPSE;
  2085. X    }
  2086. X}
  2087. X
  2088. Xvoid
  2089. Xdo_object_search(x, y, shift)
  2090. X    int            x, y;
  2091. X    unsigned int    shift;    /* Shift Key Status from XEvent */
  2092. X{
  2093. X    int            px, py;
  2094. X    char        found = 0;
  2095. X
  2096. X    init_search();
  2097. X    for (n = 0; n < objectcount;) {
  2098. X    switch (type) {
  2099. X    case O_ELLIPSE:
  2100. X        found = next_ellipse_found(x, y, TOLERANCE, &px, &py, shift);
  2101. X        break;
  2102. X    case O_POLYLINE:
  2103. X        found = next_line_found(x, y, TOLERANCE, &px, &py, shift);
  2104. X        break;
  2105. X    case O_SPLINE:
  2106. X        found = next_spline_found(x, y, TOLERANCE, &px, &py, shift);
  2107. X        break;
  2108. X    case O_TEXT:
  2109. X        found = next_text_found(x, y, TOLERANCE, &px, &py, shift);
  2110. X        break;
  2111. X    case O_ARC:
  2112. X        found = next_arc_found(x, y, TOLERANCE, &px, &py, shift);
  2113. X        break;
  2114. X    case O_COMPOUND:
  2115. X        found = next_compound_found(x, y, TOLERANCE, &px, &py, shift);
  2116. X        break;
  2117. X    }
  2118. X
  2119. X    if (found)
  2120. X        break;
  2121. X
  2122. X    switch (type) {
  2123. X    case O_ELLIPSE:
  2124. X        type = O_POLYLINE;
  2125. X        l = NULL;
  2126. X        break;
  2127. X    case O_POLYLINE:
  2128. X        type = O_SPLINE;
  2129. X        s = NULL;
  2130. X        break;
  2131. X    case O_SPLINE:
  2132. X        type = O_TEXT;
  2133. X        t = NULL;
  2134. X        break;
  2135. X    case O_TEXT:
  2136. X        type = O_ARC;
  2137. X        a = NULL;
  2138. X        break;
  2139. X    case O_ARC:
  2140. X        type = O_COMPOUND;
  2141. X        c = NULL;
  2142. X        break;
  2143. X    case O_COMPOUND:
  2144. X        type = O_ELLIPSE;
  2145. X        e = NULL;
  2146. X        break;
  2147. X    }
  2148. X    }
  2149. X    if (!found) {        /* nothing found */
  2150. X    csr_x = x;
  2151. X    csr_y = y;
  2152. X    type = -1;
  2153. X    show_objecthighlight();
  2154. X    } else if (shift) {        /* show selected object */
  2155. X    show_objecthighlight();
  2156. X    } else {            /* user selected an object */
  2157. X    erase_objecthighlight();
  2158. X    switch (type) {
  2159. X    case O_ELLIPSE:
  2160. X        manipulate(e, type, x, y, px, py);
  2161. X        break;
  2162. X    case O_POLYLINE:
  2163. X        manipulate(l, type, x, y, px, py);
  2164. X        break;
  2165. X    case O_SPLINE:
  2166. X        manipulate(s, type, x, y, px, py);
  2167. X        break;
  2168. X    case O_TEXT:
  2169. X        manipulate(t, type, x, y, px, py);
  2170. X        break;
  2171. X    case O_ARC:
  2172. X        manipulate(a, type, x, y, px, py);
  2173. X        break;
  2174. X    case O_COMPOUND:
  2175. X        manipulate(c, type, x, y, px, py);
  2176. X        break;
  2177. X    }
  2178. X    }
  2179. X}
  2180. X
  2181. Xobject_search_left(x, y, shift)
  2182. X    int            x, y;
  2183. X    unsigned int    shift;    /* Shift Key Status from XEvent */
  2184. X{
  2185. X    manipulate = handlerproc_left;
  2186. X    do_object_search(x, y, shift);
  2187. X}
  2188. X
  2189. Xobject_search_middle(x, y, shift)
  2190. X    int            x, y;
  2191. X    unsigned int    shift;    /* Shift Key Status from XEvent */
  2192. X{
  2193. X    manipulate = handlerproc_middle;
  2194. X    do_object_search(x, y, shift);
  2195. X}
  2196. X
  2197. Xobject_search_right(x, y, shift)
  2198. X    int            x, y;
  2199. X    unsigned int    shift;    /* Shift Key Status from XEvent */
  2200. X{
  2201. X    manipulate = handlerproc_right;
  2202. X    do_object_search(x, y, shift);
  2203. X}
  2204. X
  2205. Xchar
  2206. Xnext_ellipse_point_found(x, y, tol, point_num, shift)
  2207. X    int            x, y, tol, shift, *point_num;
  2208. X
  2209. X/* dirty trick - point_num is called as a `F_point *point_num' */
  2210. X{
  2211. X
  2212. X    if (!ellipse_in_mask())
  2213. X    return (0);
  2214. X    if (e == NULL)
  2215. X    e = last_ellipse(objects.ellipses);
  2216. X    else if (shift)
  2217. X    e = prev_ellipse(objects.ellipses, e);
  2218. X
  2219. X    for (; e != NULL; e = prev_ellipse(objects.ellipses, e), n++) {
  2220. X    if (abs(e->start.x - x) <= tol && abs(e->start.y - y) <= tol) {
  2221. X        *point_num = 0;
  2222. X        return (1);
  2223. X    }
  2224. X    if (abs(e->end.x - x) <= tol && abs(e->end.y - y) <= tol) {
  2225. X        *point_num = 1;
  2226. X        return (1);
  2227. X    }
  2228. X    }
  2229. X    return (0);
  2230. X}
  2231. X
  2232. Xchar
  2233. Xnext_arc_point_found(x, y, tol, point_num, shift)
  2234. X    int            x, y, tol, shift, *point_num;
  2235. X
  2236. X/* dirty trick - point_num is called as a `F_point *point_num' */
  2237. X{
  2238. X    int            i;
  2239. X
  2240. X    if (!arc_in_mask())
  2241. X    return (0);
  2242. X    if (a == NULL)
  2243. X    a = last_arc(objects.arcs);
  2244. X    else if (shift)
  2245. X    a = prev_arc(objects.arcs, a);
  2246. X
  2247. X    for (; a != NULL; a = prev_arc(objects.arcs, a), n++) {
  2248. X    for (i = 0; i < 3; i++) {
  2249. X        if (abs(a->point[i].x - x) <= tol &&
  2250. X        abs(a->point[i].y - y) <= tol) {
  2251. X        *point_num = i;
  2252. X        return (1);
  2253. X        }
  2254. X    }
  2255. X    }
  2256. X    return (0);
  2257. X}
  2258. X
  2259. Xchar
  2260. Xnext_spline_point_found(x, y, tol, p, q, shift)
  2261. X    int            x, y, tol, shift;
  2262. X    F_point      **p, **q;
  2263. X{
  2264. X    if (!anyspline_in_mask())
  2265. X    return (0);
  2266. X    if (s == NULL)
  2267. X    s = last_spline(objects.splines);
  2268. X    else if (shift)
  2269. X    s = prev_spline(objects.splines, s);
  2270. X
  2271. X    for (; s != NULL; s = prev_spline(objects.splines, s))
  2272. X    if (validspline_in_mask(s)) {
  2273. X        n++;
  2274. X        *p = NULL;
  2275. X        for (*q = s->points; *q != NULL; *p = *q, *q = (*q)->next) {
  2276. X        if (abs((*q)->x - x) <= tol && abs((*q)->y - y) <= tol)
  2277. X            return (1);
  2278. X        }
  2279. X    }
  2280. X    return (0);
  2281. X}
  2282. X
  2283. Xchar
  2284. Xnext_line_point_found(x, y, tol, p, q, shift)
  2285. X    int            x, y, tol, shift;
  2286. X    F_point      **p, **q;
  2287. X{
  2288. X    F_point       *a, *b;
  2289. X
  2290. X    if (!anyline_in_mask())
  2291. X    return (0);
  2292. X    if (l == NULL)
  2293. X    l = last_line(objects.lines);
  2294. X    else if (shift)
  2295. X    l = prev_line(objects.lines, l);
  2296. X
  2297. X    for (; l != NULL; l = prev_line(objects.lines, l))
  2298. X    if (validline_in_mask(l)) {
  2299. X        n++;
  2300. X        for (a = NULL, b = l->points; b != NULL; a = b, b = b->next) {
  2301. X        if (abs(b->x - x) <= tol && abs(b->y - y) <= tol) {
  2302. X            *p = a;
  2303. X            *q = b;
  2304. X            return (1);
  2305. X        }
  2306. X        }
  2307. X    }
  2308. X    return (0);
  2309. X}
  2310. X
  2311. Xchar
  2312. Xnext_compound_point_found(x, y, tol, p, q, shift)
  2313. X    int            x, y, tol, shift, *p, *q;
  2314. X
  2315. X/* dirty trick - p and q are called with type `F_point' */
  2316. X{
  2317. X    if (!compound_in_mask())
  2318. X    return (0);
  2319. X    if (c == NULL)
  2320. X    c = last_compound(objects.compounds);
  2321. X    else if (shift)
  2322. X    c = prev_compound(objects.compounds, c);
  2323. X
  2324. X    for (; c != NULL; c = prev_compound(objects.compounds, c), n++) {
  2325. X    if (abs(c->nwcorner.x - x) <= tol &&
  2326. X        abs(c->nwcorner.y - y) <= tol) {
  2327. X        *p = c->nwcorner.x;
  2328. X        *q = c->nwcorner.y;
  2329. X        return (1);
  2330. X    }
  2331. X    if (abs(c->nwcorner.x - x) <= tol &&
  2332. X        abs(c->secorner.y - y) <= tol) {
  2333. X        *p = c->nwcorner.x;
  2334. X        *q = c->secorner.y;
  2335. X        return (1);
  2336. X    }
  2337. X    if (abs(c->secorner.x - x) <= tol &&
  2338. X        abs(c->nwcorner.y - y) <= tol) {
  2339. X        *p = c->secorner.x;
  2340. X        *q = c->nwcorner.y;
  2341. X        return (1);
  2342. X    }
  2343. X    if (abs(c->secorner.x - x) <= tol &&
  2344. X        abs(c->secorner.y - y) <= tol) {
  2345. X        *p = c->secorner.x;
  2346. X        *q = c->secorner.y;
  2347. X        return (1);
  2348. X    }
  2349. X    }
  2350. X    return (0);
  2351. X}
  2352. X
  2353. Xvoid
  2354. Xinit_searchproc_left(handlerproc)
  2355. X    int            (*handlerproc) ();
  2356. X
  2357. X{
  2358. X    handlerproc_left = handlerproc;
  2359. X}
  2360. X
  2361. Xvoid
  2362. Xinit_searchproc_middle(handlerproc)
  2363. X    int            (*handlerproc) ();
  2364. X
  2365. X{
  2366. X    handlerproc_middle = handlerproc;
  2367. X}
  2368. X
  2369. Xvoid
  2370. Xinit_searchproc_right(handlerproc)
  2371. X    int            (*handlerproc) ();
  2372. X
  2373. X{
  2374. X    handlerproc_right = handlerproc;
  2375. X}
  2376. X
  2377. Xvoid
  2378. Xdo_point_search(x, y, shift)
  2379. X    int            x, y;
  2380. X    unsigned int    shift;    /* Shift Key Status from XEvent */
  2381. X{
  2382. X    F_point       *px, *py;
  2383. X    char        found = 0;
  2384. X
  2385. X    px = &point1;
  2386. X    py = &point2;
  2387. X    init_search();
  2388. X    for (n = 0; n < objectcount;) {
  2389. X    switch (type) {
  2390. X    case O_ELLIPSE:
  2391. X        /* dirty trick - px returns point_num */
  2392. X        found = next_ellipse_point_found(x, y, TOLERANCE, &px, shift);
  2393. X        break;
  2394. X    case O_POLYLINE:
  2395. X        found = next_line_point_found(x, y, TOLERANCE, &px, &py, shift);
  2396. X        break;
  2397. X    case O_SPLINE:
  2398. X        found = next_spline_point_found(x, y, TOLERANCE, &px, &py, shift);
  2399. X        break;
  2400. X    case O_ARC:
  2401. X        /* dirty trick - px returns point_num */
  2402. X        found = next_arc_point_found(x, y, TOLERANCE, &px, shift);
  2403. X        break;
  2404. X    case O_COMPOUND:
  2405. X        found = next_compound_point_found(x, y, TOLERANCE, &px, &py, shift);
  2406. X        break;
  2407. X    }
  2408. X    if (found) {
  2409. X        if (shift)
  2410. X        show_objecthighlight();
  2411. X        break;
  2412. X    }
  2413. X    switch (type) {
  2414. X    case O_ELLIPSE:
  2415. X        type = O_POLYLINE;
  2416. X        l = NULL;
  2417. X        break;
  2418. X    case O_POLYLINE:
  2419. X        type = O_SPLINE;
  2420. X        s = NULL;
  2421. X        break;
  2422. X    case O_SPLINE:
  2423. X        type = O_ARC;
  2424. X        a = NULL;
  2425. X        break;
  2426. X    case O_ARC:
  2427. X        type = O_COMPOUND;
  2428. X        c = NULL;
  2429. X        break;
  2430. X    case O_COMPOUND:
  2431. X        type = O_ELLIPSE;
  2432. X        e = NULL;
  2433. X        break;
  2434. X    }
  2435. X    }
  2436. X    if (!found) {
  2437. X    csr_x = x;
  2438. X    csr_y = y;
  2439. X    type = -1;
  2440. X    show_objecthighlight();
  2441. X    } else if (shift) {
  2442. X    show_objecthighlight();
  2443. X    } else {
  2444. X    erase_objecthighlight();
  2445. X    switch (type) {
  2446. X    case O_ELLIPSE:
  2447. X        manipulate(e, type, x, y, px, py);
  2448. X        break;
  2449. X    case O_POLYLINE:
  2450. X        manipulate(l, type, x, y, px, py);
  2451. X        break;
  2452. X    case O_SPLINE:
  2453. X        manipulate(s, type, x, y, px, py);
  2454. X        break;
  2455. X    case O_ARC:
  2456. X        manipulate(a, type, x, y, px, py);
  2457. X        break;
  2458. X    case O_COMPOUND:
  2459. X        manipulate(c, type, x, y, px, py);
  2460. X        break;
  2461. X    }
  2462. X    }
  2463. X}
  2464. X
  2465. Xpoint_search_left(x, y, shift)
  2466. X    int            x, y;
  2467. X    unsigned int    shift;    /* Shift Key Status from XEvent */
  2468. X{
  2469. X    manipulate = handlerproc_left;
  2470. X    do_point_search(x, y, shift);
  2471. X}
  2472. X
  2473. Xpoint_search_middle(x, y, shift)
  2474. X    int            x, y;
  2475. X    unsigned int    shift;    /* Shift Key Status from XEvent */
  2476. X{
  2477. X    manipulate = handlerproc_middle;
  2478. X    do_point_search(x, y, shift);
  2479. X}
  2480. X
  2481. Xpoint_search_right(x, y, shift)
  2482. X    int            x, y;
  2483. X    unsigned int    shift;    /* Shift Key Status from XEvent */
  2484. X{
  2485. X    manipulate = handlerproc_right;
  2486. X    do_point_search(x, y, shift);
  2487. X}
  2488. X
  2489. X/* =============================================================== */
  2490. X
  2491. X/* These are some of the original search subroutines which are still in use */
  2492. X
  2493. XF_text           *
  2494. Xtext_search(x, y)
  2495. X    int            x, y;
  2496. X{
  2497. X    F_text       *t;
  2498. X    int            xmin, xmax, ymin, ymax;
  2499. X
  2500. X    for (t = objects.texts; t != NULL; t = t->next) {
  2501. X    text_bound(t, &xmin, &ymin, &xmax, &ymax);
  2502. X    if (x >= xmin && x <= xmax &&
  2503. X        y >= ymin && y <= ymax)
  2504. X        return(t);
  2505. X    }
  2506. X    return (NULL);
  2507. X}
  2508. X
  2509. XF_compound     *
  2510. Xcompound_search(x, y, tolerance, px, py)
  2511. X    int            x, y, tolerance, *px, *py;
  2512. X{
  2513. X    F_compound       *c;
  2514. X    float        tol2;
  2515. X
  2516. X    tol2 = tolerance * tolerance;
  2517. X
  2518. X    for (c = objects.compounds; c != NULL; c = c->next) {
  2519. X    if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->nwcorner.x,
  2520. X                c->secorner.y, x, y, tolerance, tol2, px, py))
  2521. X        return (c);
  2522. X    if (close_to_vector(c->secorner.x, c->secorner.y, c->nwcorner.x,
  2523. X                c->secorner.y, x, y, tolerance, tol2, px, py))
  2524. X        return (c);
  2525. X    if (close_to_vector(c->secorner.x, c->secorner.y, c->secorner.x,
  2526. X                c->nwcorner.y, x, y, tolerance, tol2, px, py))
  2527. X        return (c);
  2528. X    if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->secorner.x,
  2529. X                c->nwcorner.y, x, y, tolerance, tol2, px, py))
  2530. X        return (c);
  2531. X    }
  2532. X    return (NULL);
  2533. X}
  2534. X
  2535. XF_compound     *
  2536. Xcompound_point_search(x, y, tol, cx, cy, fx, fy)
  2537. X    int            x, y, tol, *cx, *cy, *fx, *fy;
  2538. X{
  2539. X    F_compound       *c;
  2540. X
  2541. X    for (c = objects.compounds; c != NULL; c = c->next) {
  2542. X    if (abs(c->nwcorner.x - x) <= tol &&
  2543. X        abs(c->nwcorner.y - y) <= tol) {
  2544. X        *cx = c->nwcorner.x;
  2545. X        *cy = c->nwcorner.y;
  2546. X        *fx = c->secorner.x;
  2547. X        *fy = c->secorner.y;
  2548. X        return (c);
  2549. X    }
  2550. X    if (abs(c->nwcorner.x - x) <= tol &&
  2551. X        abs(c->secorner.y - y) <= tol) {
  2552. X        *cx = c->nwcorner.x;
  2553. X        *cy = c->secorner.y;
  2554. X        *fx = c->secorner.x;
  2555. X        *fy = c->nwcorner.y;
  2556. X        return (c);
  2557. X    }
  2558. X    if (abs(c->secorner.x - x) <= tol &&
  2559. X        abs(c->nwcorner.y - y) <= tol) {
  2560. X        *cx = c->secorner.x;
  2561. X        *cy = c->nwcorner.y;
  2562. X        *fx = c->nwcorner.x;
  2563. X        *fy = c->secorner.y;
  2564. X        return (c);
  2565. X    }
  2566. X    if (abs(c->secorner.x - x) <= tol &&
  2567. X        abs(c->secorner.y - y) <= tol) {
  2568. X        *cx = c->secorner.x;
  2569. X        *cy = c->secorner.y;
  2570. X        *fx = c->nwcorner.x;
  2571. X        *fy = c->nwcorner.y;
  2572. X        return (c);
  2573. X    }
  2574. X    }
  2575. X    return (NULL);
  2576. X}
  2577. END_OF_FILE
  2578. if test 19267 -ne `wc -c <'u_search.c'`; then
  2579.     echo shar: \"'u_search.c'\" unpacked with wrong size!
  2580. fi
  2581. # end of 'u_search.c'
  2582. fi
  2583. echo shar: End of archive 13 \(of 27\).
  2584. cp /dev/null ark13isdone
  2585. MISSING=""
  2586. 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
  2587.     if test ! -f ark${I}isdone ; then
  2588.     MISSING="${MISSING} ${I}"
  2589.     fi
  2590. done
  2591. if test "${MISSING}" = "" ; then
  2592.     echo You have unpacked all 27 archives.
  2593.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2594. else
  2595.     echo You still need to unpack the following archives:
  2596.     echo "        " ${MISSING}
  2597. fi
  2598. ##  End of shell archive.
  2599. exit 0
  2600.  
  2601. exit 0 # Just in case...
  2602. -- 
  2603.   // chris@IMD.Sterling.COM       | Send comp.sources.x submissions to:
  2604. \X/  Amiga - The only way to fly! |    sources-x@imd.sterling.com
  2605.  "It's intuitively obvious to the |
  2606.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  2607.