home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xfig / part14 / u_elastic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-27  |  20.0 KB  |  846 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_elastic.h"
  19. #include "w_canvas.h"
  20. #include "w_setup.h"
  21. #include "w_zoom.h"
  22.  
  23. extern float    compute_angle();
  24.  
  25. /********************** EXPORTS **************/
  26.  
  27. int        constrained;
  28. int        fix_x, fix_y, work_numsides;
  29. float        cur_angle;
  30. int        x1off, x2off, y1off, y2off;
  31. Cursor        cur_latexcursor;
  32. int        from_x, from_y;
  33. double        cosa, sina;
  34. int        movedpoint_num;
  35. F_point           *left_point, *right_point;
  36.  
  37. /**************** LOCAL ***********/
  38.  
  39. static void    elastic_links();
  40.  
  41. /*************************** BOXES *************************/
  42.  
  43. elastic_box(x1, y1, x2, y2)
  44.     int            x1, y1, x2, y2;
  45. {
  46.     /* line_style = RUBBER_LINE so that we don't scale it */
  47.     pw_vector(canvas_win, x1, y1, x1, y2, INV_PAINT, 1, RUBBER_LINE, 0.0,
  48.           DEFAULT_COLOR);
  49.     pw_vector(canvas_win, x1, y2, x2, y2, INV_PAINT, 1, RUBBER_LINE, 0.0,
  50.           DEFAULT_COLOR);
  51.     pw_vector(canvas_win, x2, y2, x2, y1, INV_PAINT, 1, RUBBER_LINE, 0.0,
  52.           DEFAULT_COLOR);
  53.     pw_vector(canvas_win, x2, y1, x1, y1, INV_PAINT, 1, RUBBER_LINE, 0.0,
  54.           DEFAULT_COLOR);
  55. }
  56.  
  57. elastic_movebox()
  58. {
  59.     register int    x1, y1, x2, y2;
  60.  
  61.     x1 = cur_x + x1off;
  62.     x2 = cur_x + x2off;
  63.     y1 = cur_y + y1off;
  64.     y2 = cur_y + y2off;
  65.     elastic_box(x1, y1, x2, y2);
  66.     elastic_links(cur_x - fix_x, cur_y - fix_y, 1.0, 1.0);
  67. }
  68.  
  69. moving_box(x, y)
  70.     int            x, y;
  71. {
  72.     elastic_movebox();
  73.     adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  74.     elastic_movebox();
  75. }
  76.  
  77. resizing_box(x, y)
  78.     int            x, y;
  79. {
  80.     elastic_box(fix_x, fix_y, cur_x, cur_y);
  81.     cur_x = x;
  82.     cur_y = y;
  83.     elastic_box(fix_x, fix_y, cur_x, cur_y);
  84.     boxsize_msg();
  85. }
  86.  
  87. constrained_resizing_box(x, y)
  88.     int            x, y;
  89. {
  90.     elastic_box(fix_x, fix_y, cur_x, cur_y);
  91.     adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  92.     elastic_box(fix_x, fix_y, cur_x, cur_y);
  93.     boxsize_msg();
  94. }
  95.  
  96. scaling_compound(x, y)
  97.     int            x, y;
  98. {
  99.     elastic_scalecompound(cur_c);
  100.     adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  101.     elastic_scalecompound(cur_c);
  102. }
  103.  
  104. elastic_scalecompound(c)
  105.     F_compound       *c;
  106. {
  107.     int            newx, newy, oldx, oldy, x1, y1, x2, y2;
  108.     float        newd, oldd, scalefact;
  109.  
  110.     newx = cur_x - fix_x;
  111.     newy = cur_y - fix_y;
  112.     newd = sqrt((double) (newx * newx + newy * newy));
  113.     oldx = from_x - fix_x;
  114.     oldy = from_y - fix_y;
  115.     oldd = sqrt((double) (oldx * oldx + oldy * oldy));
  116.     scalefact = newd / oldd;
  117.     x1 = fix_x + (c->secorner.x - fix_x) * scalefact;
  118.     y1 = fix_y + (c->secorner.y - fix_y) * scalefact;
  119.     x2 = fix_x + (c->nwcorner.x - fix_x) * scalefact;
  120.     y2 = fix_y + (c->nwcorner.y - fix_y) * scalefact;
  121.     elastic_box(x1, y1, x2, y2);
  122. }
  123.  
  124. /*************************** LINES *************************/
  125.  
  126. elastic_line()
  127. {
  128.     pw_vector(canvas_win, fix_x, fix_y, cur_x, cur_y,
  129.           INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  130. }
  131.  
  132. freehand_line(x, y)
  133.     int            x, y;
  134. {
  135.     elastic_line();
  136.     cur_x = x;
  137.     cur_y = y;
  138.     elastic_line();
  139.     length_msg(MSG_LENGTH);
  140. }
  141.  
  142. latex_line(x, y)
  143.     int            x, y;
  144. {
  145.     Cursor c;
  146.  
  147.     elastic_line();
  148.     latex_endpoint(fix_x, fix_y, x, y, &cur_x, &cur_y, latexarrow_mode,
  149.            (cur_pointposn == P_ANY) ? 1 : posn_rnd[cur_pointposn]);
  150.     elastic_line();
  151.     length_msg(MSG_LENGTH);
  152.     c = (x == cur_x && y == cur_y) ? null_cursor : crosshair_cursor;
  153.     if (c != cur_cursor) {
  154.     set_temp_cursor(c);
  155.     cur_cursor = c;
  156.     }
  157. }
  158.  
  159. constrainedangle_line(x, y)
  160.     int            x, y;
  161. {
  162.     float        angle, dx, dy;
  163.  
  164.     if (x == cur_x && y == cur_y)
  165.     return;
  166.  
  167.     dx = x - fix_x;
  168.     dy = fix_y - y;
  169.     if (sqrt((double) (dx * dx + dy * dy)) < 7)
  170.     return;
  171.     if (dx == 0)
  172.     angle = -90;
  173.     else
  174.     angle = 180 * atan((double) (dy / dx)) / 3.1416;
  175.  
  176.     elastic_line();
  177.     if (manhattan_mode) {
  178.     if (mountain_mode) {
  179.         if (angle < -67.5)
  180.         angle90_line(x, y);
  181.         else if (angle < -22.5)
  182.         angle135_line(x, y);
  183.         else if (angle < 22.5)
  184.         angle0_line(x, y);
  185.         else if (angle < 67.5)
  186.         angle45_line(x, y);
  187.         else
  188.         angle90_line(x, y);
  189.     } else {
  190.         if (angle < -45)
  191.         angle90_line(x, y);
  192.         else if (angle < 45)
  193.         angle0_line(x, y);
  194.         else
  195.         angle90_line(x, y);
  196.     }
  197.     } else {
  198.     if (angle < 0)
  199.         angle135_line(x, y);
  200.     else
  201.         angle45_line(x, y);
  202.     }
  203.     elastic_line();
  204.     length_msg(MSG_LENGTH);
  205. }
  206.  
  207. angle0_line(x, y)
  208.     int            x, y;
  209. {
  210.     cur_x = x;
  211.     cur_y = fix_y;
  212. }
  213.  
  214. angle90_line(x, y)
  215.     int            x, y;
  216. {
  217.     cur_y = y;
  218.     cur_x = fix_x;
  219. }
  220.  
  221. angle45_line(x, y)
  222.     int            x, y;
  223. {
  224.     if (abs(x - fix_x) < abs(y - fix_y)) {
  225.     cur_x = fix_x - y + fix_y;
  226.     cur_y = y;
  227.     } else {
  228.     cur_y = fix_y + fix_x - x;
  229.     cur_x = x;
  230.     }
  231. }
  232.  
  233. angle135_line(x, y)
  234.     int            x, y;
  235. {
  236.     if (abs(x - fix_x) < abs(y - fix_y)) {
  237.     cur_x = fix_x + y - fix_y;
  238.     cur_y = y;
  239.     } else {
  240.     cur_y = fix_y + x - fix_x;
  241.     cur_x = x;
  242.     }
  243. }
  244.  
  245. reshaping_line(x, y)
  246.     int            x, y;
  247. {
  248.     elastic_linelink();
  249.     adjust_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  250.     elastic_linelink();
  251.     /* one or two lines moving with the move point? */
  252.     if (left_point != NULL && right_point != NULL) {
  253.     length_msg2(left_point->x,left_point->y,
  254.             right_point->x,right_point->y,cur_x,cur_y);
  255.     } else if (left_point != NULL) {
  256.     altlength_msg(MSG_LENGTH,left_point->x,left_point->y);
  257.     } else if (right_point != NULL) {
  258.     altlength_msg(MSG_LENGTH,right_point->x,right_point->y);
  259.     }
  260. }
  261.  
  262. elastic_linelink()
  263. {
  264.     if (left_point != NULL) {
  265.     pw_vector(canvas_win, left_point->x, left_point->y,
  266.            cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  267.     }
  268.     if (right_point != NULL) {
  269.     pw_vector(canvas_win, right_point->x, right_point->y,
  270.            cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  271.     }
  272. }
  273.  
  274. moving_line(x, y)
  275.     int            x, y;
  276. {
  277.     elastic_moveline(new_l->points);
  278.     adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  279.     elastic_moveline(new_l->points);
  280. }
  281.  
  282. elastic_moveline(pts)
  283.     F_point       *pts;
  284. {
  285.     F_point       *p;
  286.     int            dx, dy, x, y, xx, yy;
  287.  
  288.     p = pts;
  289.     if (p->next == NULL) {    /* dot */
  290.     pw_vector(canvas_win, cur_x, cur_y, cur_x, cur_y,
  291.           INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  292.     } else {
  293.     dx = cur_x - fix_x;
  294.     dy = cur_y - fix_y;
  295.     x = p->x + dx;
  296.     y = p->y + dy;
  297.     for (p = p->next; p != NULL; x = xx, y = yy, p = p->next) {
  298.         xx = p->x + dx;
  299.         yy = p->y + dy;
  300.         pw_vector(canvas_win, x, y, xx, yy, INV_PAINT, 1,
  301.               RUBBER_LINE, 0.0, DEFAULT_COLOR);
  302.     }
  303.     }
  304.     elastic_links(dx, dy, 1.0, 1.0);
  305. }
  306.  
  307. static void
  308. elastic_links(dx, dy, sx, sy)
  309.     int            dx, dy;
  310.     float        sx, sy;
  311. {
  312.     F_linkinfo       *k;
  313.  
  314.     if (cur_linkmode == SMART_OFF)
  315.     return;
  316.  
  317.     for (k = cur_links; k != NULL; k = k->next)
  318.     if (k->prevpt == NULL) {/* dot */
  319.         pw_vector(canvas_win, k->endpt->x, k->endpt->y,
  320.               k->endpt->x, k->endpt->y,
  321.               INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  322.     } else {
  323.         if (cur_linkmode == SMART_MOVE)
  324.         pw_vector(canvas_win, k->endpt->x + dx, k->endpt->y + dy,
  325.               k->prevpt->x, k->prevpt->y,
  326.               INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  327.         else if (cur_linkmode == SMART_SLIDE) {
  328.         if (k->endpt->x == k->prevpt->x) {
  329.             if (!k->two_pts)
  330.             pw_vector(canvas_win, k->prevpt->x,
  331.                   k->prevpt->y, k->prevpt->x + dx, k->prevpt->y,
  332.                  INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  333.             pw_vector(canvas_win, k->endpt->x + dx,
  334.               k->endpt->y + dy, k->prevpt->x + dx, k->prevpt->y,
  335.                   INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  336.         } else {
  337.             if (!k->two_pts)
  338.             pw_vector(canvas_win, k->prevpt->x,
  339.                   k->prevpt->y, k->prevpt->x, k->prevpt->y + dy,
  340.                  INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  341.             pw_vector(canvas_win, k->endpt->x + dx,
  342.               k->endpt->y + dy, k->prevpt->x, k->prevpt->y + dy,
  343.                   INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  344.         }
  345.         }
  346.     }
  347. }
  348.  
  349. scaling_line(x, y)
  350.     int            x, y;
  351. {
  352.     elastic_scalepts(cur_l->points);
  353.     adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  354.     elastic_scalepts(cur_l->points);
  355.     /* could add check for box here and do a boxsize_msg */
  356. }
  357.  
  358. scaling_spline(x, y)
  359.     int            x, y;
  360. {
  361.     elastic_scalepts(cur_s->points);
  362.     adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  363.     elastic_scalepts(cur_s->points);
  364. }
  365.  
  366. elastic_scalepts(pts)
  367.     F_point       *pts;
  368. {
  369.     F_point       *p;
  370.     int            newx, newy, oldx, oldy, ox, oy, xx, yy;
  371.     float        newd, oldd, scalefact;
  372.  
  373.     p = pts;
  374.     newx = cur_x - fix_x;
  375.     newy = cur_y - fix_y;
  376.     newd = sqrt((double) (newx * newx + newy * newy));
  377.  
  378.     oldx = from_x - fix_x;
  379.     oldy = from_y - fix_y;
  380.     oldd = sqrt((double) (oldx * oldx + oldy * oldy));
  381.  
  382.     scalefact = newd / oldd;
  383.     ox = fix_x + (p->x - fix_x) * scalefact;
  384.     oy = fix_y + (p->y - fix_y) * scalefact;
  385.     for (p = p->next; p != NULL; ox = xx, oy = yy, p = p->next) {
  386.     xx = fix_x + (p->x - fix_x) * scalefact;
  387.     yy = fix_y + (p->y - fix_y) * scalefact;
  388.     pw_vector(canvas_win, ox, oy, xx, yy, INV_PAINT, 1,
  389.           RUBBER_LINE, 0.0, DEFAULT_COLOR);
  390.     }
  391. }
  392.  
  393. elastic_poly(x1, y1, x2, y2, numsides)
  394.     int            x1, y1, x2, y2, numsides;
  395. {
  396.     register float  angle;
  397.     register int    nx, ny, dx, dy, i;
  398.     float        init_angle, mag;
  399.     int            ox, oy;
  400.  
  401.     dx = x2 - x1;
  402.     dy = y2 - y1;
  403.     mag = sqrt((double) (dx * dx + dy * dy));
  404.     init_angle = compute_angle((float) dx, (float) dy);
  405.     ox = x2;
  406.     oy = y2;
  407.  
  408.     /* now append numsides points */
  409.     for (i = 1; i < numsides; i++) {
  410.     angle = init_angle - M_2PI * (float) i / (float) numsides;
  411.     if (angle < 0)
  412.         angle += M_2PI;
  413.     nx = x1 + round(mag * cos((double) angle));
  414.     ny = y1 + round(mag * sin((double) angle));
  415.     pw_vector(canvas_win, nx, ny, ox, oy, INV_PAINT, 1,
  416.           RUBBER_LINE, 0.0, DEFAULT_COLOR);
  417.     ox = nx;
  418.     oy = ny;
  419.     }
  420.     pw_vector(canvas_win, ox, oy, x2, y2, INV_PAINT, 1,
  421.           RUBBER_LINE, 0.0, DEFAULT_COLOR);
  422. }
  423.  
  424. resizing_poly(x, y)
  425.     int            x, y;
  426. {
  427.     elastic_poly(fix_x, fix_y, cur_x, cur_y, work_numsides);
  428.     cur_x = x;
  429.     cur_y = y;
  430.     work_numsides = cur_numsides;
  431.     elastic_poly(fix_x, fix_y, cur_x, cur_y, work_numsides);
  432.     length_msg(MSG_LENGTH);
  433. }
  434.  
  435. /*********************** ELLIPSES *************************/
  436.  
  437. elastic_ebr()
  438. {
  439.     register int    x1, y1, x2, y2;
  440.     int            rx, ry;
  441.  
  442.     rx = cur_x - fix_x;
  443.     ry = cur_y - fix_y;
  444.     if (cur_angle != 0.0) {
  445.     angle_ellipse(fix_x, fix_y, rx, ry, cur_angle,
  446.           INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  447.     } else {
  448.     x1 = fix_x + rx;
  449.     x2 = fix_x - rx;
  450.     y1 = fix_y + ry;
  451.     y2 = fix_y - ry;
  452.     pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
  453.          RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  454.     }
  455. }
  456.  
  457. resizing_ebr(x, y)
  458.     int            x, y;
  459. {
  460.     elastic_ebr();
  461.     cur_x = x;
  462.     cur_y = y;
  463.     elastic_ebr();
  464.     length_msg(MSG_RADIUS);
  465. }
  466.  
  467. constrained_resizing_ebr(x, y)
  468.     int            x, y;
  469. {
  470.     elastic_ebr();
  471.     adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  472.     elastic_ebr();
  473.     length_msg(MSG_RADIUS);
  474. }
  475.  
  476. elastic_ebd()
  477. {
  478.     int            centx,centy;
  479.     centx = (fix_x+cur_x)/2;
  480.     centy = (fix_y+cur_y)/2;
  481.     if (cur_angle != 0.0) {
  482.     angle_ellipse(centx, centy, abs(cur_x-fix_x)/2, 
  483.           abs(cur_y-fix_y)/2, cur_angle,
  484.           INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  485.     } else {
  486.     pw_curve(canvas_win, fix_x, fix_y, cur_x, cur_y,
  487.          INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  488.     }
  489.     length_msg(MSG_DIAM);
  490. }
  491.  
  492. resizing_ebd(x, y)
  493.     int            x, y;
  494. {
  495.     elastic_ebd();
  496.     cur_x = x;
  497.     cur_y = y;
  498.     elastic_ebd();
  499.     length_msg(MSG_DIAM);
  500. }
  501.  
  502. constrained_resizing_ebd(x, y)
  503.     int            x, y;
  504. {
  505.     elastic_ebd();
  506.     adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  507.     elastic_ebd();
  508.     length_msg(MSG_DIAM);
  509. }
  510.  
  511. elastic_cbr()
  512. {
  513.     register int    radius, x1, y1, x2, y2, rx, ry;
  514.  
  515.     rx = cur_x - fix_x;
  516.     ry = cur_y - fix_y;
  517.     radius = round(sqrt((double) (rx * rx + ry * ry)));
  518.     x1 = fix_x + radius;
  519.     x2 = fix_x - radius;
  520.     y1 = fix_y + radius;
  521.     y2 = fix_y - radius;
  522.     pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
  523.          RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  524. }
  525.  
  526. resizing_cbr(x, y)
  527.     int            x, y;
  528. {
  529.     elastic_cbr();
  530.     cur_x = x;
  531.     cur_y = y;
  532.     elastic_cbr();
  533.     length_msg(MSG_RADIUS);
  534. }
  535.  
  536. elastic_cbd()
  537. {
  538.     register int    x1, y1, x2, y2;
  539.     int            radius, rx, ry;
  540.  
  541.     rx = (cur_x - fix_x) / 2;
  542.     ry = (cur_y - fix_y) / 2;
  543.     radius = round(sqrt((double) (rx * rx + ry * ry)));
  544.     x1 = fix_x + rx + radius;
  545.     x2 = fix_x + rx - radius;
  546.     y1 = fix_y + ry + radius;
  547.     y2 = fix_y + ry - radius;
  548.     pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
  549.          RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  550. }
  551.  
  552. resizing_cbd(x, y)
  553.     int            x, y;
  554. {
  555.     elastic_cbd();
  556.     cur_x = x;
  557.     cur_y = y;
  558.     elastic_cbd();
  559.     length_msg(MSG_DIAM);
  560. }
  561.  
  562. constrained_resizing_cbd(x, y)
  563.     int            x, y;
  564. {
  565.     elastic_cbd();
  566.     adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  567.     elastic_cbd();
  568.     length_msg(MSG_DIAM);
  569. }
  570.  
  571. elastic_moveellipse()
  572. {
  573.     register int    x1, y1, x2, y2;
  574.  
  575.     x1 = cur_x + x1off;
  576.     x2 = cur_x + x2off;
  577.     y1 = cur_y + y1off;
  578.     y2 = cur_y + y2off;
  579.     if (cur_angle != 0.0) {
  580.     angle_ellipse((x1+x2)/2, (y1+y2)/2, abs(x1-x2)/2, abs(y1-y2)/2, cur_angle,
  581.           INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  582.     } else {
  583.     pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
  584.          RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  585.     }
  586. }
  587.  
  588. moving_ellipse(x, y)
  589.     int            x, y;
  590. {
  591.     elastic_moveellipse();
  592.     adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  593.     elastic_moveellipse();
  594. }
  595.  
  596. elastic_scaleellipse(e)
  597.     F_ellipse       *e;
  598. {
  599.     register int    x1, y1, x2, y2;
  600.     int            rx, ry;
  601.     int            newx, newy, oldx, oldy;
  602.     float        newd, oldd, scalefact;
  603.  
  604.     newx = cur_x - fix_x;
  605.     newy = cur_y - fix_y;
  606.     newd = sqrt((double) (newx * newx + newy * newy));
  607.  
  608.     oldx = from_x - fix_x;
  609.     oldy = from_y - fix_y;
  610.     oldd = sqrt((double) (oldx * oldx + oldy * oldy));
  611.  
  612.     scalefact = newd / oldd;
  613.  
  614.     rx = e->radiuses.x * scalefact;
  615.     ry = e->radiuses.y * scalefact;
  616.     if (cur_angle != 0.0) {
  617.     angle_ellipse(e->center.x, e->center.y, rx, ry, cur_angle,
  618.           INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  619.     } else {
  620.     x1 = fix_x + rx;
  621.     x2 = fix_x - rx;
  622.     y1 = fix_y + ry;
  623.     y2 = fix_y - ry;
  624.     pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
  625.          RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
  626.     }
  627. }
  628.  
  629. scaling_ellipse(x, y)
  630.     int            x, y;
  631. {
  632.     elastic_scaleellipse(cur_e);
  633.     adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  634.     elastic_scaleellipse(cur_e);
  635. }
  636.  
  637. /*************************** ARCS *************************/
  638.  
  639. reshaping_arc(x, y)
  640.     int            x, y;
  641. {
  642.     elastic_arclink();
  643.     adjust_pos(x, y, cur_a->point[movedpoint_num].x,
  644.            cur_a->point[movedpoint_num].y, &cur_x, &cur_y);
  645.     elastic_arclink();
  646.     if (movedpoint_num == 1) {
  647.     /* middle point */
  648.     length_msg2(cur_a->point[0].x, cur_a->point[0].y,
  649.             cur_a->point[2].x, cur_a->point[2].y,
  650.             cur_x, cur_y);
  651.     } else {
  652.     /* end point */
  653.     altlength_msg(MSG_LENGTH,cur_a->point[1].x,cur_a->point[1].y);
  654.     }
  655. }
  656.  
  657. elastic_arclink()
  658. {
  659.     switch (movedpoint_num) {
  660.     case 0:
  661.     pw_vector(canvas_win, cur_x, cur_y,
  662.           cur_a->point[1].x, cur_a->point[1].y,
  663.           INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  664.     break;
  665.     case 1:
  666.     pw_vector(canvas_win, cur_a->point[0].x, cur_a->point[0].y,
  667.           cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0,
  668.           DEFAULT_COLOR);
  669.     pw_vector(canvas_win, cur_a->point[2].x, cur_a->point[2].y,
  670.           cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0,
  671.           DEFAULT_COLOR);
  672.     break;
  673.     default:
  674.     pw_vector(canvas_win, cur_a->point[1].x, cur_a->point[1].y,
  675.           cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0,
  676.           DEFAULT_COLOR);
  677.     }
  678. }
  679.  
  680. moving_arc(x, y)
  681.     int            x, y;
  682. {
  683.     elastic_movearc(new_a);
  684.     adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  685.     elastic_movearc(new_a);
  686. }
  687.  
  688. elastic_movearc(a)
  689.     F_arc       *a;
  690. {
  691.     int            dx, dy;
  692.  
  693.     dx = cur_x - fix_x;
  694.     dy = cur_y - fix_y;
  695.     pw_vector(canvas_win, a->point[0].x + dx, a->point[0].y + dy,
  696.           a->point[1].x + dx, a->point[1].y + dy,
  697.           INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  698.     pw_vector(canvas_win, a->point[1].x + dx, a->point[1].y + dy,
  699.           a->point[2].x + dx, a->point[2].y + dy,
  700.           INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  701. }
  702.  
  703. scaling_arc(x, y)
  704.     int            x, y;
  705. {
  706.     elastic_scalearc(cur_a);
  707.     adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  708.     elastic_scalearc(cur_a);
  709. }
  710.  
  711. elastic_scalearc(a)
  712.     F_arc       *a;
  713. {
  714.     int            newx, newy, oldx, oldy;
  715.     float        newd, oldd, scalefact;
  716.     F_pos        p0, p1, p2;
  717.  
  718.     newx = cur_x - fix_x;
  719.     newy = cur_y - fix_y;
  720.     newd = sqrt((double) (newx * newx + newy * newy));
  721.  
  722.     oldx = from_x - fix_x;
  723.     oldy = from_y - fix_y;
  724.     oldd = sqrt((double) (oldx * oldx + oldy * oldy));
  725.  
  726.     scalefact = newd / oldd;
  727.  
  728.     p0 = a->point[0];
  729.     p1 = a->point[1];
  730.     p2 = a->point[2];
  731.     p0.x = fix_x + (p0.x - fix_x) * scalefact;
  732.     p0.y = fix_y + (p0.y - fix_y) * scalefact;
  733.     p1.x = fix_x + (p1.x - fix_x) * scalefact;
  734.     p1.y = fix_y + (p1.y - fix_y) * scalefact;
  735.     p2.x = fix_x + (p2.x - fix_x) * scalefact;
  736.     p2.y = fix_y + (p2.y - fix_y) * scalefact;
  737.  
  738.     pw_vector(canvas_win, p0.x, p0.y, p1.x, p1.y,
  739.           INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  740.     pw_vector(canvas_win, p1.x, p1.y, p2.x, p2.y,
  741.           INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
  742. }
  743.  
  744. /*************************** TEXT *************************/
  745.  
  746. moving_text(x, y)
  747.     int            x, y;
  748. {
  749.     elastic_movetext();
  750.     adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  751.     elastic_movetext();
  752. }
  753.  
  754. elastic_movetext()
  755. {
  756.     pw_text(canvas_win, cur_x + x1off, cur_y + y1off, INV_PAINT,
  757.         new_t->fontstruct, new_t->cstring, new_t->color);
  758. }
  759.  
  760.  
  761. /*************************** SPLINES *************************/
  762.  
  763. moving_spline(x, y)
  764.     int            x, y;
  765. {
  766.     elastic_moveline(new_s->points);
  767.     adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
  768.     elastic_moveline(new_s->points);
  769. }
  770.  
  771. /*********** AUXILIARY FUNCTIONS FOR CONSTRAINED MOVES ******************/
  772.  
  773. adjust_box_pos(curs_x, curs_y, orig_x, orig_y, ret_x, ret_y)
  774.     int            curs_x, curs_y, orig_x, orig_y;
  775.     int           *ret_x, *ret_y;
  776. {
  777.     int            xx, sgn_csr2fix_x, yy, sgn_csr2fix_y;
  778.     double        mag_csr2fix_x, mag_csr2fix_y;
  779.  
  780.     switch (constrained) {
  781.     case MOVE_ARB:
  782.     *ret_x = curs_x;
  783.     *ret_y = curs_y;
  784.     break;
  785.     case BOX_HSTRETCH:
  786.     *ret_x = curs_x;
  787.     *ret_y = orig_y;
  788.     break;
  789.     case BOX_VSTRETCH:
  790.     *ret_x = orig_x;
  791.     *ret_y = curs_y;
  792.     break;
  793.     default:
  794.     /* calculate where scaled and stretched box corners would be */
  795.     xx = curs_x - fix_x;
  796.     sgn_csr2fix_x = signof(xx);
  797.     mag_csr2fix_x = (double) abs(xx);
  798.  
  799.     yy = curs_y - fix_y;
  800.     sgn_csr2fix_y = signof(yy);
  801.     mag_csr2fix_y = (double) abs(yy);
  802.  
  803.     if (mag_csr2fix_x * sina > mag_csr2fix_y * cosa) {    /* above diagonal */
  804.         *ret_x = curs_x;
  805.         if (constrained == BOX_SCALE) {
  806.         if (cosa == 0.0) {
  807.             *ret_y = fix_y + sgn_csr2fix_y * (int) (mag_csr2fix_x);
  808.         } else {
  809.             *ret_y = fix_y + sgn_csr2fix_y * (int) (mag_csr2fix_x * sina / cosa);
  810.         }
  811.         } else {
  812.             *ret_y = fix_y + sgn_csr2fix_y * abs(fix_y - orig_y);
  813.          }
  814.     } else {
  815.         *ret_y = curs_y;
  816.         if (constrained == BOX_SCALE) {
  817.         if (sina == 0.0) {
  818.             *ret_x = fix_x + sgn_csr2fix_x * (int) (mag_csr2fix_y);
  819.         } else {
  820.             *ret_x = fix_x + sgn_csr2fix_x * (int) (mag_csr2fix_y * cosa / sina);
  821.         }
  822.         } else {
  823.         *ret_x = fix_x + sgn_csr2fix_x * abs(fix_x - orig_x);
  824.         }
  825.     }
  826.     } /* switch */
  827. }
  828.  
  829. adjust_pos(curs_x, curs_y, orig_x, orig_y, ret_x, ret_y)
  830.     int            curs_x, curs_y, orig_x, orig_y;
  831.     int           *ret_x, *ret_y;
  832. {
  833.     if (constrained) {
  834.     if (abs(orig_x - curs_x) > abs(orig_y - curs_y)) {
  835.         *ret_x = curs_x;
  836.         *ret_y = orig_y;
  837.     } else {
  838.         *ret_x = orig_x;
  839.         *ret_y = curs_y;
  840.     }
  841.     } else {
  842.     *ret_x = curs_x;
  843.     *ret_y = curs_y;
  844.     }
  845. }
  846.