home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / segal / view.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-24  |  13.8 KB  |  600 lines

  1. /*
  2.  *    view.c - for use with SEGAL
  3.  *
  4.  *    By Bryan Skene
  5.  */
  6.  
  7. #include "common.h"
  8.  
  9. #define MAX_VCANV_WIDTH        256 
  10. #define MAX_VCANV_HEIGHT    256
  11.  
  12. /************************************************************/
  13. void
  14. view_setup()
  15. {
  16.     int view_w, view_h, canv_w, canv_h, slid_x, slid_y,
  17.         zoom_x, zoom_y, pref_x, pref_w;
  18.     int max_zcanv_width, max_zcanv_height;
  19.  
  20.     /* set size and location */
  21.  
  22.     /***** Z Aspect *****/
  23.     win[WIN_VZ].canv_x = xv_get(View_win->msg_image, XV_X, NULL) + 20;
  24.     win[WIN_VZ].canv_y = xv_get(View_win->but_image, XV_Y, NULL) + 100;
  25.     win[WIN_VZ].canv_w = win[WIN_VZ].img_c * win[WIN_VZ].zoom_mag;
  26.     win[WIN_VZ].canv_h = win[WIN_VZ].img_r * win[WIN_VZ].zoom_mag;
  27.     
  28.     canv_w = win[WIN_VZ].canv_w;
  29.     canv_h = win[WIN_VZ].canv_h;
  30.  
  31.     if(segal.disp_xy) {
  32.         max_zcanv_width = MAX_VCANV_WIDTH;
  33.         max_zcanv_height = MAX_VCANV_HEIGHT;
  34.     }
  35.     else {
  36.         max_zcanv_width = 2 * MAX_VCANV_WIDTH;
  37.         max_zcanv_height = 2 * MAX_VCANV_HEIGHT;
  38.     }
  39.  
  40.     RANGE(win[WIN_VZ].canv_w, 0, max_zcanv_width)
  41.     RANGE(win[WIN_VZ].canv_h, 0, max_zcanv_height)
  42.  
  43.     if(canv_w <= max_zcanv_width) xv_destroy_safe(win[WIN_VZ].h_sbar);
  44.     if(canv_h <= max_zcanv_height) xv_destroy_safe(win[WIN_VZ].v_sbar);
  45.     xv_set(View_win->canv_z,
  46.         XV_SHOW, TRUE,
  47.         XV_X, win[WIN_VZ].canv_x,
  48.         XV_Y, win[WIN_VZ].canv_y,
  49.         XV_WIDTH, win[WIN_VZ].canv_w,
  50.         XV_HEIGHT, win[WIN_VZ].canv_h,
  51.         CANVAS_WIDTH, canv_w,
  52.         CANVAS_HEIGHT, canv_h,
  53.         CANVAS_AUTO_SHRINK, FALSE,
  54.         CANVAS_AUTO_EXPAND, FALSE,
  55.         NULL);
  56.  
  57.     if(canv_w > max_zcanv_width)
  58.     win[WIN_VZ].h_sbar = (Scrollbar) xv_create(View_win->canv_z, SCROLLBAR,
  59.         SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
  60.         SCROLLBAR_PIXELS_PER_UNIT, win[WIN_VZ].zoom_mag,
  61.         SCROLLBAR_OBJECT_LENGTH, win[WIN_VZ].img_c,
  62.         SCROLLBAR_PAGE_LENGTH, max_zcanv_width,
  63.         SCROLLBAR_VIEW_LENGTH, max_zcanv_width,
  64.         NULL);
  65.  
  66.     if(canv_h > max_zcanv_height)
  67.     win[WIN_VZ].v_sbar = (Scrollbar) xv_create(View_win->canv_z, SCROLLBAR,
  68.         SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
  69.         SCROLLBAR_PIXELS_PER_UNIT, win[WIN_VZ].zoom_mag,
  70.         SCROLLBAR_OBJECT_LENGTH, win[WIN_VZ].img_r,
  71.         SCROLLBAR_PAGE_LENGTH, max_zcanv_height,
  72.         SCROLLBAR_VIEW_LENGTH, max_zcanv_height,
  73.         NULL);
  74.  
  75.     slid_x = win[WIN_VZ].canv_x + win[WIN_VZ].canv_w - 90;
  76.     slid_y = win[WIN_VZ].canv_y - 30 + 4;
  77.     zoom_x = win[WIN_VZ].canv_x;
  78.     zoom_y = slid_y - 28;
  79.  
  80.     if(segal.r3d) {
  81.         xv_set(View_win->set_frame_z,
  82.             XV_SHOW, TRUE,
  83.             XV_X, slid_x,
  84.             XV_Y, slid_y,
  85.             PANEL_VALUE, win[WIN_VZ].f,
  86.             PANEL_MIN_VALUE, 0,
  87.             PANEL_MAX_VALUE, segal.f - 1,
  88.             PANEL_SLIDER_WIDTH, win[WIN_VZ].canv_h,
  89.             NULL);
  90.     }
  91.     else {
  92.         xv_set(View_win->set_frame_z,
  93.             XV_SHOW, FALSE,
  94.             NULL);
  95.     }
  96.  
  97.     xv_set(View_win->set_zoom_z,
  98.         XV_SHOW, TRUE,
  99.         XV_X, zoom_x,
  100.         XV_Y, zoom_y,
  101.         NULL);
  102.  
  103.     /***** X Aspect *****/
  104.     if(segal.disp_xy && segal.r3d) {
  105.     win[WIN_VX].canv_w = win[WIN_VX].img_c * win[WIN_VX].zoom_mag;
  106.     win[WIN_VX].canv_h = win[WIN_VX].img_r * win[WIN_VX].zoom_mag;
  107.     
  108.     canv_w = win[WIN_VX].canv_w;
  109.     canv_h = win[WIN_VX].canv_h;
  110.  
  111.     RANGE(win[WIN_VX].canv_w, 0, MAX_VCANV_WIDTH)
  112.     RANGE(win[WIN_VX].canv_h, 0, MAX_VCANV_HEIGHT)
  113.  
  114.     if(canv_w <= MAX_VCANV_WIDTH) xv_destroy_safe(win[WIN_VX].h_sbar);
  115.     if(canv_h <= MAX_VCANV_HEIGHT) xv_destroy_safe(win[WIN_VX].v_sbar);
  116.  
  117.     zoom_x = xv_get(View_win->but_preferences, XV_X, NULL)
  118.         + xv_get(View_win->but_preferences, XV_WIDTH, NULL) + 20;
  119.     win[WIN_VX].canv_x = zoom_x;
  120.     slid_x = zoom_x + win[WIN_VX].canv_w - 90;
  121.  
  122.     zoom_y = xv_get(View_win->msg_image, XV_Y, NULL) - 4;
  123.     slid_y = zoom_y + 25;
  124.     win[WIN_VX].canv_y = slid_y + 25;
  125.  
  126.     xv_set(View_win->canv_x,
  127.         XV_SHOW, TRUE,
  128.         XV_X, win[WIN_VX].canv_x,
  129.         XV_Y, win[WIN_VX].canv_y,
  130.         XV_WIDTH, win[WIN_VX].canv_w,
  131.         XV_HEIGHT, win[WIN_VX].canv_h,
  132.         CANVAS_WIDTH, canv_w,
  133.         CANVAS_HEIGHT, canv_h,
  134.         CANVAS_AUTO_SHRINK, FALSE,
  135.         CANVAS_AUTO_EXPAND, FALSE,
  136.         NULL);
  137.  
  138.     if(canv_w > MAX_VCANV_WIDTH)
  139.     win[WIN_VX].h_sbar = (Scrollbar) xv_create(View_win->canv_x, SCROLLBAR,
  140.         SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
  141.         SCROLLBAR_PIXELS_PER_UNIT, win[WIN_VX].zoom_mag,
  142.         SCROLLBAR_OBJECT_LENGTH, win[WIN_VX].img_c,
  143.         SCROLLBAR_PAGE_LENGTH, MAX_VCANV_WIDTH,
  144.         SCROLLBAR_VIEW_LENGTH, MAX_VCANV_WIDTH,
  145.         NULL);
  146.  
  147.     if(canv_h > MAX_VCANV_HEIGHT)
  148.     win[WIN_VX].v_sbar = (Scrollbar) xv_create(View_win->canv_x, SCROLLBAR,
  149.         SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
  150.         SCROLLBAR_PIXELS_PER_UNIT, win[WIN_VX].zoom_mag,
  151.         SCROLLBAR_OBJECT_LENGTH, win[WIN_VX].img_r,
  152.         SCROLLBAR_PAGE_LENGTH, MAX_VCANV_HEIGHT,
  153.         SCROLLBAR_VIEW_LENGTH, MAX_VCANV_HEIGHT,
  154.         NULL);
  155.  
  156.     xv_set(View_win->set_frame_x,
  157.         XV_SHOW, TRUE,
  158.         XV_X, slid_x,
  159.         XV_Y, slid_y,
  160.         PANEL_VALUE, win[WIN_VX].f,
  161.         PANEL_MIN_VALUE, 0,
  162.         PANEL_MAX_VALUE, segal.c - 1,
  163.         PANEL_SLIDER_WIDTH, win[WIN_VX].canv_h,
  164.         NULL);
  165.  
  166.     xv_set(View_win->set_zoom_x,
  167.         XV_SHOW, TRUE,
  168.         XV_X, zoom_x,
  169.         XV_Y, zoom_y,
  170.         NULL);
  171.  
  172.     /***** Y Aspect *****/
  173.     win[WIN_VY].canv_w = win[WIN_VY].img_c * win[WIN_VY].zoom_mag;
  174.     win[WIN_VY].canv_h = win[WIN_VY].img_r * win[WIN_VY].zoom_mag;
  175.     
  176.     canv_w = win[WIN_VY].canv_w;
  177.     canv_h = win[WIN_VY].canv_h;
  178.  
  179.     RANGE(win[WIN_VY].canv_w, 0, MAX_VCANV_WIDTH)
  180.     RANGE(win[WIN_VY].canv_h, 0, MAX_VCANV_HEIGHT)
  181.  
  182.     if(canv_w <= MAX_VCANV_WIDTH) xv_destroy_safe(win[WIN_VY].h_sbar);
  183.     if(canv_h <= MAX_VCANV_HEIGHT) xv_destroy_safe(win[WIN_VY].v_sbar);
  184.  
  185.     /* zoom_x does not change here */
  186.     win[WIN_VY].canv_x = zoom_x;
  187.     slid_x = zoom_x + win[WIN_VY].canv_w - 90;
  188.  
  189.     zoom_y = win[WIN_VX].canv_y + win[WIN_VX].canv_h + 30;
  190.     slid_y = zoom_y + 25;
  191.     win[WIN_VY].canv_y = slid_y + 25;
  192.  
  193.     xv_set(View_win->canv_y,
  194.         XV_SHOW, TRUE,
  195.         XV_X, win[WIN_VY].canv_x,
  196.         XV_Y, win[WIN_VY].canv_y,
  197.         XV_WIDTH, win[WIN_VY].canv_w,
  198.         XV_HEIGHT, win[WIN_VY].canv_h,
  199.         CANVAS_WIDTH, canv_w,
  200.         CANVAS_HEIGHT, canv_h,
  201.         CANVAS_AUTO_SHRINK, FALSE,
  202.         CANVAS_AUTO_EXPAND, FALSE,
  203.         NULL);
  204.  
  205.     if(canv_w > MAX_VCANV_WIDTH)
  206.     win[WIN_VY].h_sbar = (Scrollbar) xv_create(View_win->canv_y, SCROLLBAR,
  207.         SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
  208.         SCROLLBAR_PIXELS_PER_UNIT, win[WIN_VY].zoom_mag,
  209.         SCROLLBAR_OBJECT_LENGTH, win[WIN_VY].img_c,
  210.         SCROLLBAR_PAGE_LENGTH, MAX_VCANV_WIDTH,
  211.         SCROLLBAR_VIEW_LENGTH, MAX_VCANV_WIDTH,
  212.         NULL);
  213.  
  214.     if(canv_h > MAX_VCANV_HEIGHT)
  215.     win[WIN_VY].v_sbar = (Scrollbar) xv_create(View_win->canv_y, SCROLLBAR,
  216.         SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
  217.         SCROLLBAR_PIXELS_PER_UNIT, win[WIN_VY].zoom_mag,
  218.         SCROLLBAR_OBJECT_LENGTH, win[WIN_VY].img_r,
  219.         SCROLLBAR_PAGE_LENGTH, MAX_VCANV_HEIGHT,
  220.         SCROLLBAR_VIEW_LENGTH, MAX_VCANV_HEIGHT,
  221.         NULL);
  222.  
  223.     xv_set(View_win->set_frame_y,
  224.         XV_SHOW, TRUE,
  225.         XV_X, slid_x,
  226.         XV_Y, slid_y,
  227.         PANEL_VALUE, win[WIN_VY].f,
  228.         PANEL_MIN_VALUE, 0,
  229.         PANEL_MAX_VALUE, segal.r - 1,
  230.         PANEL_SLIDER_WIDTH, win[WIN_VY].canv_h,
  231.         NULL);
  232.  
  233.     xv_set(View_win->set_zoom_y,
  234.         XV_SHOW, TRUE,
  235.         XV_X, zoom_x,
  236.         XV_Y, zoom_y,
  237.         NULL);
  238.     } /* display X & Y && this is a 3d image */
  239.     else {
  240.     /* make X & Y canvases, messages, etc. invisible */
  241.         xv_set(View_win->canv_x,
  242.             XV_SHOW, FALSE,
  243.             NULL);
  244.         xv_set(View_win->set_frame_x,
  245.             XV_SHOW, FALSE,
  246.             NULL);
  247.         xv_set(View_win->set_zoom_x,
  248.             XV_SHOW, FALSE,
  249.             NULL);
  250.         xv_set(View_win->canv_y,
  251.             XV_SHOW, FALSE,
  252.             NULL);
  253.         xv_set(View_win->set_frame_y,
  254.             XV_SHOW, FALSE,
  255.             NULL);
  256.         xv_set(View_win->set_zoom_y,
  257.             XV_SHOW, FALSE,
  258.             NULL);
  259.     }
  260.  
  261.     /***** View Window *****/
  262.     if(segal.disp_xy) {
  263.         view_w = MAX(win[WIN_VX].canv_x + win[WIN_VX].canv_w, win[WIN_VY].canv_x + win[WIN_VY].canv_w);
  264.         view_h = MAX(win[WIN_VY].canv_y + win[WIN_VY].canv_h, win[WIN_VZ].canv_y + win[WIN_VZ].canv_h);
  265.     }
  266.     else {
  267.         pref_x = xv_get(View_win->but_preferences, XV_X, NULL);
  268.         pref_w = xv_get(View_win->but_preferences, XV_WIDTH, NULL);
  269.  
  270.         view_w = MAX(win[WIN_VZ].canv_x + win[WIN_VZ].canv_w,
  271.             pref_x + pref_w);
  272.         view_h = win[WIN_VZ].canv_y + win[WIN_VZ].canv_h;
  273.     }
  274.  
  275.     (void) xv_set(View_win->win,
  276.         XV_WIDTH, view_w + 40,
  277.         XV_HEIGHT, view_h + 30,
  278.         NULL);
  279.  
  280.     if((int) xv_get(View_win->win, XV_SHOW, NULL) == TRUE)
  281.         return;
  282.  
  283.     xv_set(View_win->win, XV_SHOW, TRUE, NULL);
  284.  
  285.     XFlush(display); /* a good idea right about here */
  286. }
  287.  
  288. /************************************************************/
  289. void
  290. redisplay_all()
  291. {
  292.     void map_buffers();
  293.  
  294.     int i;
  295.  
  296.     vprint"redisplaying all buffers ... \n");
  297.     For_all_windows win[i].repaint = TRUE;
  298.     map_buffers();
  299. }
  300.  
  301. /************************************************************/
  302. void
  303. redisplay_view()
  304. {
  305.     void map_buffers();
  306.  
  307.     int i;
  308.  
  309.     vprint"redisplaying view buffers ... \n");
  310.     For_all_view win[i].repaint = TRUE;
  311.     map_buffers();
  312. }
  313.  
  314. /************************************************************/
  315. void
  316. view_event(win_id, event)
  317. int win_id;
  318. Event *event;
  319. {
  320. /* Events:
  321.  *    shift+click    : display pixel value.
  322.  *    click left    : coordinate aspects.
  323.  *    click middle    : draw crop rectangle.
  324.  *    click right    : draw polygon points.
  325.  */
  326.     void display_pixel_value();
  327.     void coordinate_aspects();
  328.     void fix_2d_coords();
  329.     void draw_crop_rectangle();
  330.     void add_to_polygon();
  331.  
  332.     int x, y, f, which_button;
  333.  
  334.     if(!img.loaded) return;
  335.  
  336.     x = event_x(event) / win[win_id].zoom_mag;
  337.     y = event_y(event) / win[win_id].zoom_mag;
  338.     f = win[win_id].f;
  339.     RANGE(x, 0, win[win_id].img_c - 1)
  340.     RANGE(y, 0, win[win_id].img_r - 1)
  341.  
  342.     if(event_meta_is_down(event)) {
  343.     }
  344.  
  345.     else if(event_ctrl_is_down(event)) {
  346.     }
  347.  
  348.     else if(event_shift_is_down(event)) {
  349.         switch(event_id(event)) {
  350.         case MS_RIGHT :
  351.         case MS_LEFT :
  352.         case MS_MIDDLE :
  353.             if(event_is_down(event)) {
  354.                 xv_set(View_win->msg_pixel_value,
  355.                     XV_SHOW, TRUE,
  356.                     NULL);
  357.                 display_pixel_value(win[win_id].aspect, x, y, f);
  358.             }
  359.  
  360.             else if(event_is_up(event))
  361.                 xv_set(View_win->msg_pixel_value,
  362.                     XV_SHOW, FALSE,
  363.                     NULL);
  364.             break;
  365.         case LOC_DRAG :
  366.             display_pixel_value(win[win_id].aspect, x, y, f);
  367.             break;
  368.         }
  369.     }
  370.  
  371.     /* other events */
  372.     else if(event_is_down(event)) switch(event_id(event)) {
  373.         case MS_LEFT :
  374.         /* coordinate aspects */
  375.             coordinate_aspects(win_id, x, y);
  376.             break;
  377.  
  378.         case MS_MIDDLE :
  379.         /* begin to crop a rectangle */
  380.             which_button = MS_MIDDLE;
  381.             if(event_is_down(event)) {
  382.                 /* erase old crop rectangle */
  383.                 draw_crop_rectangle();
  384.  
  385.                 crop.win_id = win_id;
  386.                 crop.x1 = crop.x2 = x;
  387.                 crop.y1 = crop.y2 = y;
  388.             }
  389.             else if(event_is_up(event)) {
  390.                 fix_2d_coords(&crop.x1, &crop.y1, &crop.x2, &crop.y2);
  391.             }
  392.  
  393.             break;
  394.  
  395.         case MS_RIGHT :
  396.         /* draw a polygon point */
  397.             add_to_polygon(win_id, x, y);
  398.             break;
  399.  
  400.         case LOC_DRAG :
  401.             if(which_button == MS_MIDDLE) {
  402.             /* continue to crop a rectangle */
  403.                 /* erase the old crop rectangle */
  404.                 draw_crop_rectangle();
  405.  
  406.                 /* get new crop values */
  407.                 crop.x2 = x;
  408.                 crop.y2 = y;
  409.  
  410.                 /* draw new one */
  411.                 draw_crop_rectangle();
  412.             }
  413.             break;
  414.         default :
  415.             break;
  416.     }
  417. }
  418.  
  419. /************************************************************/
  420. void
  421. draw_crop_rectangle()
  422. {
  423.     void draw_rectangle();
  424.  
  425.     if(crop.x1 != crop.x2 && crop.y1 != crop.y2)
  426.         draw_rectangle(crop.win_id, crop.x1, crop.y1, crop.x2, crop.y2);
  427. }
  428.  
  429. /************************************************************/
  430. void
  431. draw_rectangle(win_id, x1, y1, x2, y2)
  432. int win_id, x1, y1, x2, y2;
  433. {
  434. /* expects x1 < x2 and y1 < y2 */
  435.     void fix_2d_coords();
  436.  
  437.     int zx1, zy1, zx2, zy2;
  438.  
  439.     XSetFunction(display, gc, GXinvert);
  440.  
  441.     fix_2d_coords(&x1, &y1, &x2, &y2);
  442.  
  443.     zx1 = x1 * win[win_id].zoom_mag;
  444.     zy1 = y1 * win[win_id].zoom_mag;
  445.     zx2 = x2 * win[win_id].zoom_mag;
  446.     zy2 = y2 * win[win_id].zoom_mag;
  447.     XDrawRectangle(display, win[win_id].xid, gc,
  448.         zx1, zy1, zx2 - zx1, zy2 - zy1);
  449.  
  450.     XSetFunction(display, gc, GXcopy);
  451. }
  452.  
  453. /************************************************************/
  454. void
  455. fix_2d_coords(x1, y1, x2, y2)
  456. int *x1, *y1, *x2, *y2;
  457. {
  458.     if(*x1 > *x2) swap(x1, x2);
  459.     if(*y1 > *y2) swap(y1, y2);
  460. }
  461.  
  462. /************************************************************/
  463. void
  464. display_pixel_value(aspect_id, x, y, f)
  465. int aspect_id, x, y, f;
  466. {
  467.     void get_3d_coords();
  468.  
  469.     int x1, y1, f1;
  470.     char foo[80];
  471.  
  472.     get_3d_coords(aspect_id, ASPECT_Z, x, y, f, &x1, &y1, &f1);
  473.  
  474.     /* coordinates displayed in the z aspect .... */
  475.     sprintf(foo, "Pixel value: (%3d,%3d,%3d) = %3d",
  476.         x1, y1, f1, ibuf[f1][y1][x1]);
  477.  
  478.     xv_set(View_win->msg_pixel_value,
  479.         PANEL_LABEL_STRING, foo,
  480.         NULL);
  481. }
  482.  
  483. /************************************************************/
  484. void
  485. coordinate_aspects(win_id, mx, my)
  486. int win_id, mx, my;
  487. {
  488.     void redisplay_view();
  489.     void get_3d_coords();
  490.     u_long standout();
  491.  
  492.     int i, x, y, f;
  493.     XRectangle recs[3]; /* 3 aspects */
  494.  
  495.     For_all_view {
  496.         get_3d_coords(win_id, i, mx, my, win[win_id].f, &x, &y, &f);
  497.         if(i != win_id) {
  498.             win[i].f = f;
  499.             recs[i].x = (short) ((x-1) * win[i].zoom_mag);
  500.             recs[i].y = (short) ((y-1) * win[i].zoom_mag);
  501.         }
  502.         else {
  503.             recs[i].x = (short) ((mx-1) * win[i].zoom_mag);
  504.             recs[i].y = (short) ((my-1) * win[i].zoom_mag);
  505.         }
  506.         recs[i].width = (unsigned short) win[i].zoom_mag * 5;
  507.         recs[i].height = (unsigned short) win[i].zoom_mag * 5;
  508.     }
  509.  
  510.     xv_set(View_win->set_frame_x,
  511.         PANEL_VALUE, win[WIN_VX].f,
  512.         NULL);
  513.  
  514.     xv_set(View_win->set_frame_y,
  515.         PANEL_VALUE, win[WIN_VY].f,
  516.         NULL);
  517.  
  518.     xv_set(View_win->set_frame_z,
  519.         PANEL_VALUE, win[WIN_VZ].f,
  520.         NULL);
  521.  
  522.     redisplay_view();
  523.  
  524.     XSetForeground(display, gc, standout(RED));
  525.     For_all_view XDrawRectangle(display, win[i].xid, gc, recs[i].x,
  526.             recs[i].y, recs[i].width, recs[i].height);
  527. }
  528.  
  529. /************************************************************/
  530. void
  531. add_to_polygon(win_id, x, y)
  532. int win_id, x, y;
  533. {
  534. }
  535.  
  536. /************************************************************/
  537. void
  538. get_3d_coords(asp_in, asp_out, x0, y0, f0, x1, y1, f1)
  539. int asp_in, asp_out, x0, y0, f0;
  540. int *x1, *y1, *f1;
  541. {
  542.     if(asp_in == asp_out) {
  543.         *x1 = x0;
  544.         *y1 = y0;
  545.         *f1 = f0;
  546.     }
  547.     else switch(asp_in) {
  548.     case ASPECT_X :
  549.         switch(asp_out) {
  550.         case ASPECT_Y :
  551.             *x1 = f0;
  552.             *y1 = y0;
  553.             *f1 = segal.r - 1 - x0;
  554.             break;
  555.         case ASPECT_Z :
  556.             *x1 = f0;
  557.             *y1 = x0;
  558.             *f1 = segal.f - 1 - y0;
  559.             break;
  560.         default :
  561.             break;
  562.         }
  563.         break;
  564.     case ASPECT_Y :
  565.         switch(asp_out) {
  566.         case ASPECT_X :
  567.             *x1 = segal.r - 1 - f0;
  568.             *y1 = y0;
  569.             *f1 = x0;
  570.             break;
  571.         case ASPECT_Z :
  572.             *x1 = x0;
  573.             *y1 = segal.r - 1 - f0;
  574.             *f1 = segal.f - 1 - y0;
  575.             break;
  576.         default :
  577.             break;
  578.         }
  579.         break;
  580.     case ASPECT_Z :
  581.         switch(asp_out) {
  582.         case ASPECT_X :
  583.             *x1 = y0;
  584.             *y1 = segal.f - 1 - f0;
  585.             *f1 = x0;
  586.             break;
  587.         case ASPECT_Y :
  588.             *x1 = x0;
  589.             *y1 = segal.f - 1 - f0;
  590.             *f1 = segal.r - 1 - y0;
  591.             break;
  592.         default :
  593.             break;
  594.         }
  595.         break;
  596.     default:
  597.         break;
  598.     }
  599. }
  600.