home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xfig2.8 / part07 / addpt.c next >
C/C++ Source or Header  |  1990-07-02  |  8KB  |  330 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : August 1985.
  7.  *    2nd revision : March 1988.
  8.  *
  9.  *    %W%    %G%
  10. */
  11. #include "fig.h"
  12. #include "resources.h"
  13. #include "alloc.h"
  14. #include "func.h"
  15. #include "object.h"
  16. #include "paintop.h"
  17.  
  18. #define            TOLERANCE    3
  19.  
  20. extern F_line        *line_search();
  21. extern F_spline        *spline_search();
  22. extern            (*canvas_kbd_proc)();
  23. extern            (*canvas_locmove_proc)();
  24. extern            (*canvas_leftbut_proc)();
  25. extern            (*canvas_middlebut_proc)();
  26. extern            (*canvas_rightbut_proc)();
  27. extern            null_proc();
  28. extern            set_popupmenu();
  29. extern            determine_angle();
  30.  
  31. extern int        manhattan_mode, mountain_mode;
  32. extern int        latexline_mode, latexarrow_mode;
  33. extern int        cur_x, cur_y, fix_x, fix_y;
  34. extern int        pointmarker_shown;
  35. extern F_line        *line;
  36. extern F_spline        *spline;
  37.  
  38. extern F_point        *added_point;
  39. extern F_point        *left_point, *right_point;
  40.  
  41. extern int        init_point_adding();
  42. extern int        move_addedpoint();
  43. extern int        fix_linepoint_adding();
  44. extern int        mm_fix_linepoint_adding();
  45. extern int        fix_splinepoint_adding();
  46. extern int        latex_elasticline();
  47.  
  48. static F_line        *cur_line;
  49. static F_spline        *cur_spline;
  50.  
  51. point_adding_selected()
  52. {
  53.     canvas_kbd_proc = null_proc;
  54.     canvas_locmove_proc = null_proc;
  55.     canvas_leftbut_proc = init_point_adding;
  56.     canvas_middlebut_proc = null_proc;
  57.     canvas_rightbut_proc = set_popupmenu;
  58.     set_cursor(&pick9_cursor);
  59.     }
  60.  
  61. init_point_adding(x, y)
  62. int    x, y;
  63. {
  64.     int    px, py;
  65.  
  66.     if ((cur_line = line_search(x, y, TOLERANCE, &px, &py)) != NULL) {
  67.         if (cur_line->type == T_BOX || cur_line->type == T_ARC_BOX) {
  68.         put_msg("Adding points to a box is not allowed");
  69.         return;
  70.         }
  71.         init_linepointadding(px, py);
  72.         }
  73.     else if ((cur_spline = spline_search(x,y,TOLERANCE,&px,&py)) != NULL){
  74.         init_splinepointadding(px, py);
  75.         }
  76.     else {
  77.         return;
  78.         }
  79.     canvas_leftbut_proc = canvas_rightbut_proc = null_proc;
  80.     erase_pointmarker();
  81.     }
  82.  
  83. wrapup_pointadding()
  84. {
  85.     show_pointmarker();
  86.     point_adding_selected();
  87.     }
  88.  
  89. /**************************  spline  *******************************/
  90.  
  91. init_splinepointadding(px, py)
  92. int        px, py;
  93. {
  94.     find_endpoints(cur_spline->points, px, py, &left_point, &right_point);
  95.     set_temp_cursor(&null_cursor);
  96.     win_setmouseposition(canvas_win, px, py);
  97.     cur_x = px; cur_y = py;
  98.     if (left_point == NULL && closed_spline(cur_spline)) {
  99.         /* The added_point is between the 1st and 2nd point. */
  100.         left_point = right_point;
  101.         right_point = right_point->next;
  102.         }
  103.     draw_addedlink(INV_PAINT);
  104.     canvas_locmove_proc = move_addedpoint;
  105.     canvas_middlebut_proc = fix_splinepoint_adding;
  106.     }
  107.  
  108. fix_splinepoint_adding(x, y)
  109. int    x, y;
  110. {
  111.     F_point        *p;
  112.  
  113.     if (NULL == (Point_malloc(p))) {
  114.         put_msg(Err_mem);
  115.         wrapup_pointadding();
  116.         return;
  117.         }
  118.     clean_up();
  119.     added_point = p;
  120.     added_point->x = x;
  121.     added_point->y = y;
  122.     draw_addedlink(INV_PAINT);
  123.     if (-1 == splinepoint_adding(cur_spline, added_point))
  124.         wrapup_pointadding();
  125.     set_action_object(F_ADD_POINT, O_SPLINE);
  126.     set_latestspline(cur_spline);
  127.     wrapup_pointadding();
  128.     }
  129.  
  130. /*
  131. Warning: Do not change the value of the pointers left_point and
  132. right_point.  Added_point is always inserted between left_point
  133. and right_point, except in two cases. 
  134.     (1) left_point is NULL, the added_point will be prepended
  135.         to the list of points. This case will never
  136.         occur if the spline is closed (periodic).
  137.     (2) right_point is NULL, the added_point will be appended
  138.         to the end of the list.
  139. */
  140.  
  141. splinepoint_adding(spline, added_point)
  142. F_spline    *spline;
  143. F_point        *added_point;
  144. {
  145.     F_control    *c;
  146.  
  147.     set_temp_cursor(&wait_cursor);
  148.     if (int_spline(spline)) {    /* Interpolated spline */
  149.         if (NULL == (Control_malloc(c))) {
  150.         put_msg(Err_mem);
  151.         return(-1);
  152.         }
  153.         }
  154.     if (pointmarker_shown) toggle_splinepointmarker(spline);  
  155.     draw_spline(spline, ERASE); /* erase old spline */
  156.     if (left_point == NULL) {
  157.         added_point->next = spline->points;
  158.         spline->points = added_point;
  159.         }
  160.     else {
  161.         added_point->next = right_point;
  162.         left_point->next = added_point;
  163.         }
  164.  
  165.     if (int_spline(spline)) {    /* Interpolated spline */
  166.         c->next = spline->controls;
  167.         spline->controls = c;
  168.         remake_control_points(spline);
  169.         }
  170.  
  171.     draw_spline(spline, PAINT); /* draw the modified spline */
  172.     if (pointmarker_shown) toggle_splinepointmarker(spline);  
  173.     reset_cursor();
  174.     set_modifiedflag();
  175.     return(1);
  176.     }
  177.  
  178. /***************************  line  ********************************/
  179.  
  180. init_linepointadding(px, py)
  181. int    px, py;
  182. {
  183.     find_endpoints(cur_line->points,px,py,&left_point,&right_point);
  184.     set_temp_cursor(&null_cursor);
  185.     win_setmouseposition(canvas_win, px, py);
  186.     cur_x = fix_x = px; cur_y = fix_y = py;
  187.     if (left_point == NULL && cur_line->type == T_POLYGON) {
  188.         left_point = right_point;
  189.         right_point = right_point->next;
  190.         }
  191.     if (left_point != NULL && right_point != NULL)
  192.         pw_vector(canvas_win, left_point->x, left_point->y,
  193.         right_point->x, right_point->y, INV_PAINT, 
  194.         cur_line->thickness, cur_line->style, cur_line->style_val);
  195.     draw_addedlink(INV_PAINT);
  196.     if (latexline_mode || latexarrow_mode) {
  197.         canvas_locmove_proc = latex_elasticline;
  198.         canvas_middlebut_proc = mm_fix_linepoint_adding;
  199.         }
  200.     if( (mountain_mode || manhattan_mode) &&
  201.        (left_point == NULL || right_point == NULL) )
  202.     {
  203.         canvas_locmove_proc = determine_angle;
  204.         canvas_middlebut_proc = mm_fix_linepoint_adding;
  205.     }
  206.     else
  207.     {
  208.         canvas_locmove_proc = move_addedpoint;
  209.         canvas_middlebut_proc = fix_linepoint_adding;
  210.     }
  211.     }
  212.  
  213. fix_linepoint_adding(x, y)
  214. int    x, y;
  215. {
  216.     F_point        *p;
  217.  
  218.     if (NULL == (Point_malloc(p))) {
  219.         put_msg(Err_mem);
  220.         wrapup_pointadding();
  221.         return;
  222.         }
  223.     clean_up();
  224.     added_point = p;
  225.     added_point->x = x;
  226.     added_point->y = y;
  227.     draw_addedlink(INV_PAINT);
  228.     linepoint_adding(cur_line, added_point);
  229.     set_action_object(F_ADD_POINT, O_POLYLINE);
  230.     set_latestline(cur_line);
  231.     wrapup_pointadding();
  232.     }
  233.  
  234. mm_fix_linepoint_adding()
  235. {
  236.     F_point        *p;
  237.  
  238.     if (NULL == (Point_malloc(p))) {
  239.         put_msg(Err_mem);
  240.         wrapup_pointadding();
  241.         return;
  242.         }
  243.     clean_up();
  244.     added_point = p;
  245.     added_point->x = cur_x;
  246.     added_point->y = cur_y;
  247.     draw_addedlink(INV_PAINT);
  248.     linepoint_adding(cur_line, added_point);
  249.     set_action_object(F_ADD_POINT, O_POLYLINE);
  250.     set_latestline(cur_line);
  251.     wrapup_pointadding();
  252.     }
  253.  
  254. linepoint_adding(line, added_point)
  255. F_line    *line;
  256. F_point    *added_point;
  257. {
  258.     if (pointmarker_shown) toggle_linepointmarker(line);
  259.     draw_line(line, ERASE);
  260.     if (left_point == NULL) {
  261.         added_point->next = line->points;
  262.         line->points = added_point;
  263.         }
  264.     else {
  265.         added_point->next = left_point->next;
  266.         left_point->next = added_point;
  267.         }
  268.     draw_line(line, PAINT);
  269.     if (pointmarker_shown) toggle_linepointmarker(line);  
  270.     set_modifiedflag();
  271.     }
  272.  
  273. /*******************************************************************/
  274.  
  275. /*
  276. If (x,y) is close to a point, q, fp points to q and sp points to q->next
  277. (right).  However if q is the first point, fp contains NULL and sp points to q.
  278. */
  279.  
  280. find_endpoints(p, x, y, fp, sp)
  281. F_point    *p, **fp, **sp;
  282. int    x, y;
  283. {
  284.     int    d;
  285.     F_point    *a = NULL, *b = p;
  286.  
  287.     if (x == b->x && y == b->y) {
  288.         *fp = a;
  289.         *sp = b;
  290.         return;
  291.         }
  292.  
  293.     for (a = p, b = p->next; b != NULL; a = b, b = b->next){
  294.         if (x == b->x && y == b->y) {
  295.         *fp = b;
  296.         *sp = b->next;
  297.         return;
  298.         }
  299.         if (close_to_vector(a->x, a->y, b->x, b->y, x, y, 1, 1.0, &d, &d)) {
  300.         *fp = a;
  301.         *sp = b;
  302.         return;
  303.         }
  304.         }
  305.     *fp = a;
  306.     *sp = b;
  307.     }
  308.  
  309. draw_addedlink(op)
  310. int    op;
  311. {
  312.     if (left_point != NULL) {
  313.         pw_vector(canvas_win, left_point->x, left_point->y,
  314.             cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
  315.        }
  316.     if (right_point != NULL) {
  317.         pw_vector(canvas_win, right_point->x, 
  318.             right_point->y, cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
  319.         }
  320.     }
  321.  
  322. move_addedpoint(x, y)
  323. int    x, y;
  324. {
  325.     draw_addedlink(INV_PAINT);
  326.     cur_x = x;
  327.     cur_y = y;
  328.     draw_addedlink(INV_PAINT);
  329.     }
  330.