home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xfig / part06 / e_addpt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-27  |  7.6 KB  |  303 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1985 by Supoj Sutanthavibul
  4.  *
  5.  * "Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both the copyright
  8.  * notice and this permission notice appear in supporting documentation. 
  9.  * No representations are made about the suitability of this software for 
  10.  * any purpose.  It is provided "as is" without express or implied warranty."
  11.  */
  12.  
  13. #include "fig.h"
  14. #include "resources.h"
  15. #include "mode.h"
  16. #include "object.h"
  17. #include "paintop.h"
  18. #include "u_create.h"
  19. #include "u_elastic.h"
  20. #include "u_search.h"
  21. #include "w_canvas.h"
  22. #include "w_mousefun.h"
  23. extern void    force_positioning(), force_nopositioning();
  24. extern void    force_anglegeom(), force_noanglegeom();
  25.  
  26. static int    init_point_adding();
  27. static int    fix_linepoint_adding();
  28. static int    fix_splinepoint_adding();
  29. static int    init_linepointadding();
  30. static int    init_splinepointadding();
  31. static int    find_endpoints();
  32.  
  33. point_adding_selected()
  34. {
  35.     set_mousefun("break/add here", "", "");
  36.     canvas_kbd_proc = null_proc;
  37.     canvas_locmove_proc = null_proc;
  38.     init_searchproc_left(init_point_adding);
  39.     canvas_leftbut_proc = object_search_left;
  40.     canvas_middlebut_proc = null_proc;
  41.     canvas_rightbut_proc = null_proc;
  42.     set_cursor(pick9_cursor);
  43.     force_nopositioning();
  44.     force_anglegeom();
  45.     constrained = MOVE_ARB;
  46. }
  47.  
  48. static int
  49. init_point_adding(p, type, x, y, px, py)
  50.     char       *p;
  51.     int            type;
  52.     int            x, y;
  53.     int            px, py;
  54. {
  55.     set_action_on();
  56.     set_mousefun("place new point", "", "cancel");
  57.     draw_mousefun_canvas();
  58.     set_temp_cursor(null_cursor);
  59.     win_setmouseposition(canvas_win, px, py);
  60.     switch (type) {
  61.     case O_POLYLINE:
  62.     cur_l = (F_line *) p;
  63.     /* the search routine will ensure that we don't have a box */
  64.     init_linepointadding(px, py);
  65.     break;
  66.     case O_SPLINE:
  67.     cur_s = (F_spline *) p;
  68.     init_splinepointadding(px, py);
  69.     break;
  70.     default:
  71.     return;
  72.     }
  73.     force_positioning();
  74.     /* draw in rubber-band line */
  75.     elastic_linelink();
  76.  
  77.     if (left_point == NULL || right_point == NULL) {
  78.     if (latexline_mode || latexarrow_mode) {
  79.         canvas_locmove_proc = latex_line;
  80.         return;
  81.     }
  82.     if (mountain_mode || manhattan_mode) {
  83.         canvas_locmove_proc = constrainedangle_line;
  84.         return;
  85.     }
  86.     } else {
  87.     force_noanglegeom();
  88.     }
  89.     canvas_locmove_proc = reshaping_line;
  90. }
  91.  
  92. static
  93. wrapup_pointadding()
  94. {
  95.     reset_action_on();
  96.     point_adding_selected();
  97.     draw_mousefun_canvas();
  98. }
  99.  
  100. static
  101. cancel_pointadding()
  102. {
  103.     elastic_linelink();
  104.     wrapup_pointadding();
  105. }
  106.  
  107. static
  108. cancel_line_pointadding()
  109. {
  110.     if (left_point != NULL && right_point != NULL)
  111.     pw_vector(canvas_win, left_point->x, left_point->y,
  112.           right_point->x, right_point->y, INV_PAINT,
  113.           cur_l->thickness, cur_l->style, cur_l->style_val,
  114.           cur_l->color);
  115.     cancel_pointadding();
  116. }
  117.  
  118. /**************************  spline  *******************************/
  119.  
  120. static int
  121. init_splinepointadding(px, py)
  122.     int            px, py;
  123. {
  124.     find_endpoints(cur_s->points, px, py, &left_point, &right_point);
  125.  
  126.     cur_x = fix_x = px;
  127.     cur_y = fix_y = py;
  128.     if (left_point == NULL && closed_spline(cur_s)) {
  129.     /* The added_point is between the 1st and 2nd point. */
  130.     left_point = right_point;
  131.     right_point = right_point->next;
  132.     }
  133.     canvas_leftbut_proc = fix_splinepoint_adding;
  134.     canvas_rightbut_proc = cancel_pointadding;
  135. }
  136.  
  137. static
  138. fix_splinepoint_adding(x, y)
  139.     int            x, y;
  140. {
  141.     F_point       *p;
  142.  
  143.     (*canvas_locmove_proc) (x, y);
  144.     if ((p = create_point()) == NULL) {
  145.     wrapup_pointadding();
  146.     return;
  147.     }
  148.     p->x = cur_x;
  149.     p->y = cur_y;
  150.     elastic_linelink();
  151.     splinepoint_adding(cur_s, left_point, p, right_point);
  152.     wrapup_pointadding();
  153. }
  154.  
  155. /*
  156.  * Added_point is always inserted between left_point and
  157.  * right_point, except in two cases. (1) left_point is NULL, the added_point
  158.  * will be prepended to the list of points. This case will never occur if the
  159.  * spline is closed (periodic). (2) right_point is NULL, the added_point will
  160.  * be appended to the end of the list.
  161.  */
  162.  
  163. splinepoint_adding(spline, left_point, added_point, right_point)
  164.     F_spline       *spline;
  165.     F_point       *left_point, *added_point, *right_point;
  166. {
  167.     F_control       *c;
  168.  
  169.     if (int_spline(spline)) {    /* Interpolated spline */
  170.     if ((c = create_cpoint()) == NULL)
  171.         return;
  172.     }
  173.     set_temp_cursor(wait_cursor);
  174.     mask_toggle_splinemarker(spline);
  175.     draw_spline(spline, ERASE); /* erase old spline */
  176.     if (left_point == NULL) {
  177.     added_point->next = spline->points;
  178.     spline->points = added_point;
  179.     } else {
  180.     added_point->next = right_point;
  181.     left_point->next = added_point;
  182.     }
  183.  
  184.     if (int_spline(spline)) {    /* Interpolated spline */
  185.     c->next = spline->controls;
  186.     spline->controls = c;
  187.     remake_control_points(spline);
  188.     }
  189.     draw_spline(spline, PAINT); /* draw the modified spline */
  190.     mask_toggle_splinemarker(spline);
  191.     clean_up();
  192.     set_modifiedflag();
  193.     set_last_prevpoint(left_point);
  194.     set_last_selectedpoint(added_point);
  195.     set_action_object(F_ADD_POINT, O_SPLINE);
  196.     set_latestspline(spline);
  197.     reset_cursor();
  198. }
  199.  
  200. /***************************  line  ********************************/
  201.  
  202. static int
  203. init_linepointadding(px, py)
  204.     int            px, py;
  205. {
  206.     find_endpoints(cur_l->points, px, py, &left_point, &right_point);
  207.  
  208.     /* set cur_x etc at new point coords */
  209.     cur_x = fix_x = px;
  210.     cur_y = fix_y = py;
  211.     if (left_point == NULL && cur_l->type == T_POLYGON) {
  212.     left_point = right_point;
  213.     right_point = right_point->next;
  214.     }
  215.     /* erase line segment where new point is */
  216.     if (left_point != NULL && right_point != NULL)
  217.     pw_vector(canvas_win, left_point->x, left_point->y,
  218.           right_point->x, right_point->y, ERASE,
  219.           cur_l->thickness, cur_l->style, cur_l->style_val,
  220.           cur_l->color);
  221.  
  222.     canvas_leftbut_proc = fix_linepoint_adding;
  223.     canvas_rightbut_proc = cancel_line_pointadding;
  224. }
  225.  
  226. static
  227. fix_linepoint_adding(x, y)
  228.     int x, y;
  229. {
  230.     F_point       *p;
  231.  
  232.     (*canvas_locmove_proc) (x, y);
  233.     if ((p = create_point()) == NULL) {
  234.     wrapup_pointadding();
  235.     return;
  236.     }
  237.     p->x = cur_x;
  238.     p->y = cur_y;
  239.     elastic_linelink();
  240.     linepoint_adding(cur_l, left_point, p);
  241.     wrapup_pointadding();
  242. }
  243.  
  244. linepoint_adding(line, left_point, added_point)
  245.     F_line       *line;
  246.     F_point       *left_point, *added_point;
  247. {
  248.     mask_toggle_linemarker(line);
  249.     draw_line(line, ERASE);
  250.     if (left_point == NULL) {
  251.     added_point->next = line->points;
  252.     line->points = added_point;
  253.     } else {
  254.     added_point->next = left_point->next;
  255.     left_point->next = added_point;
  256.     }
  257.     draw_line(line, PAINT);
  258.     clean_up();
  259.     mask_toggle_linemarker(line);
  260.     set_action_object(F_ADD_POINT, O_POLYLINE);
  261.     set_latestline(line);
  262.     set_last_prevpoint(left_point);
  263.     set_last_selectedpoint(added_point);
  264.     set_modifiedflag();
  265. }
  266.  
  267. /*******************************************************************/
  268.  
  269. /*
  270.  * If (x,y) is close to a point, q, fp points to q and sp points to q->next
  271.  * (right).  However if q is the first point, fp contains NULL and sp points
  272.  * to q.
  273.  */
  274.  
  275. static int
  276. find_endpoints(p, x, y, fp, sp)
  277.     F_point       *p, **fp, **sp;
  278.     int            x, y;
  279. {
  280.     int            d;
  281.     F_point       *a = NULL, *b = p;
  282.  
  283.     if (x == b->x && y == b->y) {
  284.     *fp = a;
  285.     *sp = b;
  286.     return;
  287.     }
  288.     for (a = p, b = p->next; b != NULL; a = b, b = b->next) {
  289.     if (x == b->x && y == b->y) {
  290.         *fp = b;
  291.         *sp = b->next;
  292.         return;
  293.     }
  294.     if (close_to_vector(a->x, a->y, b->x, b->y, x, y, 1, 1.0, &d, &d)) {
  295.         *fp = a;
  296.         *sp = b;
  297.         return;
  298.     }
  299.     }
  300.     *fp = a;
  301.     *sp = b;
  302. }
  303.