File m_basic.c
**************

File header
===========

     <<m_basic.c : *>>=
     <<m_basic.c : copyright and license -- m_basic.c - copyright and license>>

     /* DO NOT read or edit this file ! Use ../noweb/m_basic.nw instead */

     <<m_basic.c : include directives -- m_basic.c - include directives>>
     <<m_basic.c : mil_x() -- m_basic.c - mil_x()>>
     <<m_basic.c : mil_y() -- m_basic.c - mil_y()>>
     <<m_basic.c : pix_x() -- m_basic.c - pix_x()>>
     <<m_basic.c : pix_y() -- m_basic.c - pix_y()>>
     <<m_basic.c : WORLDtoSCREEN() -- m_basic.c - WORLDtoSCREEN()>>
     <<m_basic.c : SCREENtoWORLD() -- m_basic.c - SCREENtoWORLD()>>
     <<m_basic.c : snap_grid() -- m_basic.c - snap_grid()>>
     <<m_basic.c : SCREENabs() -- m_basic.c - SCREENabs()>>
     <<m_basic.c : WORLDabs() -- m_basic.c - WORLDabs()>>
     <<m_basic.c : set_window() -- m_basic.c - set_window()>>
     <<m_basic.c : fix_x() -- m_basic.c - fix_x()>>
     <<m_basic.c : fix_y() -- m_basic.c - fix_y()>>
     <<m_basic.c : on_snap() -- m_basic.c - on_snap()>>
     <<m_basic.c : HALFSPACE and sPOINT typedefs() -- m_basic.c - HALFSPACE and sPOINT typedefs()>>
     <<m_basic.c : SCREENencode_halfspace() -- m_basic.c - SCREENencode_halfspace()>>
     <<m_basic.c : WORLDencode_halfspace() -- m_basic.c - WORLDencode_halfspace()>>
     <<m_basic.c : SCREENclip_change() -- m_basic.c - SCREENclip_change()>>
     <<m_basic.c : clip_nochange() -- m_basic.c - clip_nochange()>>
     <<m_basic.c : visible() -- m_basic.c - visible()>>
     <<m_basic.c : rotate_point() -- m_basic.c - rotate_point()>>
     <<m_basic.c : rotate_point_90() -- m_basic.c - rotate_point_90()>>
     <<m_basic.c : PAPERSIZEtoWORLD() -- m_basic.c - PAPERSIZEtoWORLD()>>
     <<m_basic.c : return_zoom_number() -- m_basic.c - return_zoom_number()>>
     <<m_basic.c : round_5_2_1() -- m_basic.c - round_5_2_1()>>

     <<m_basic.c : copyright and license>>=
     /* gEDA - GPL Electronic Design Automation
      * libgeda - gEDA's library
      * Copyright (C) 1998-2000 Ales V. Hvezda
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
      * the Free Software Foundation; either version 2 of the License, or
      * (at your option) any later version.
      *
      * This program is distributed in the hope that it will be useful,
      * but WITHOUT ANY WARRANTY; without even the implied warranty of
      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      * GNU General Public License for more details.
      *
      * You should have received a copy of the GNU General Public License
      * along with this program; if not, write to the Free Software
      * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
      */

     <<m_basic.c : include directives>>=
     #include <config.h>

     #include <stdio.h>
     #include <math.h>

     #include <gtk/gtk.h>
     #include <libguile.h>

     #include "defines.h"
     #include "struct.h" /* why should I include these hack, just for prototype ? */
     #include "globals.h"

     #include "../include/prototype.h"

     #ifdef HAVE_LIBDMALLOC
     #include <dmalloc.h>
     #endif

Function mil_x()
================

 -- Function: mil_x w_current val

     <<m_basic.c : mil_x()>>=
     int
     mil_x(TOPLEVEL *w_current, int val)
     {
       double i;
       double fval;
       int j;

     #if 0 /* removed for speed improvements */
       double fw0,fw1,fw,fval;
       fw1 = w_current->page_current->right;
       fw0 = w_current->page_current->left;
       fw  = w_current->width;
     #endif

       fval = val;
       i = fval * w_current->page_current->to_world_x_constant +
       w_current->page_current->left;

       /* i -= mil_x_tw2;
          i = ((i) / 100 ) * 100; I don't think we need this
          i += mil_x_tw1;*/

     #ifdef HAS_RINT
       j = rint(i);
     #else
       j = i;
     #endif

       return(j);
     }

          Defines :
          mil_x,
           -- m_basic.c - fix_x(),
           -- m_basic.c - WORLDtoSCREEN(),
           -- m_basic.c - SCREENtoWORLD(),
           -- m_basic.c - set_window().

     }

Function mil_y()
================

 -- Function: mil_y w_current val

     <<m_basic.c : mil_y()>>=
     int
     mil_y(TOPLEVEL *w_current, int val)
     {
       double i;
       double fval;
       int j;

     #if 0 /* removed for speed improvements */
       double fw0,fw1,fw,fval;
       fw1 = w_current->page_current->bottom;
       fw0 = w_current->page_current->top;
       fw  = w_current->height;
     #endif

       fval = w_current->height - val;
       i = fval * w_current->page_current->to_world_y_constant +
       w_current->page_current->top;

       /* i = ((i) / 100 ) * 100; I don't think we need this */
       /* i += mil_y_tw1; or this*/

     #ifdef HAS_RINT
       j = rint(i);
     #else
       j = i;
     #endif

       return(j);
     }

          Defines :
          mil_y,
           -- m_basic.c - fix_y(),
           -- m_basic.c - WORLDtoSCREEN(),
           -- m_basic.c - SCREENtoWORLD(),
           -- m_basic.c - set_window().

     }

Function pix_x()
================

 -- Function: pix_x w_current val

     <<m_basic.c : pix_x()>>=
     int
     pix_x(TOPLEVEL *w_current, int val)
     {

       double i;
       int j;

     #if 0 /* removed for speed */
       double fs,f0,f1,f;
       f0 = w_current->page_current->left;
       f1 = w_current->page_current->right;
       fs = w_current->width;
       f = w_current->width / (f1 - f0);
     #endif

       i = w_current->page_current->to_screen_x_constant *
       (double)(val - w_current->page_current->left);

     #ifdef HAS_RINT
       j = rint(i);
     #else
       j = i;
     #endif

       /* this is a temp solution to fix the wrapping associated with */
       /* X coords being greated/less than than 2^15 */
       if (j >= 32768) {
         j = 32767;
       }
       if (j <= -32768) {
         j = -32767;
       }

       return(j);
     }

          Defines :
          pix_x,
           -- m_basic.c - fix_x(),
           -- m_basic.c - WORLDtoSCREEN(),
           -- m_basic.c - set_window().

     }

Function pix_y()
================

 -- Function: pix_y w_current val

     <<m_basic.c : pix_y()>>=
     int
     pix_y(TOPLEVEL *w_current, int val)
     {
       double i;
       int j;

     #if 0 /* removed for speed */
       double fs,f0,f1,f;
       f0 = w_current->page_current->top;
       f1 = w_current->page_current->bottom;
       fs = w_current->height;
       f = fs / (f1 - f0); /* fs was w_current->height */
     #endif
       i = w_current->height - (
                                w_current->page_current->to_screen_y_constant *
                                (double)(val - w_current->page_current->top));

     #ifdef HAS_RINT
       j = rint(i);
     #else
       j = i;
     #endif

       /* this is a temp solution to fix the wrapping associated with */
       /* X coords being greated/less than than 2^15 */
       if (j >= 32768) {
         j = 32767;
       }
       if (j <= -32768) {
         j = -32767;
       }

       return(j);
     }

          Defines :
          pix_y,
           -- m_basic.c - fix_y(),
           -- m_basic.c - WORLDtoSCREEN(),
           -- m_basic.c - set_window().

     }

Function WORLDtoSCREEN()
========================

 -- Function: WORLDtoSCREEN w_current x y mil_x mil_y

     <<m_basic.c : WORLDtoSCREEN()>>=
     void
     WORLDtoSCREEN(TOPLEVEL *w_current, int x, int y, int *mil_x, int *mil_y)
     {
       *mil_x = pix_x(w_current, x);
       *mil_y = pix_y(w_current, y);
     }

          Defines :
          .

          Uses :
          mil_x,  -- m_basic.c - mil_x().
          mil_y,  -- m_basic.c - mil_y().
          pix_x,  -- m_basic.c - pix_x().
          pix_y,  -- m_basic.c - pix_y().

     }

Function snap_grid()
====================

 -- Function: snap_grid w_current input

     <<m_basic.c : snap_grid()>>=
     int
     snap_grid(TOPLEVEL *w_current, int input)
     {
       int p, m, n;
       int sign, value, snap_grid;

       if (!w_current->snap) {
         return(input);
       }

       snap_grid = w_current->snap_size;

       /* this code was inspired from killustrator, it's much simpler than mine */
       sign = ( input < 0 ? -1 : 1 );
       value = abs(input);

       p = value / snap_grid;
       m = value % snap_grid;
       n = p * snap_grid;
       if (m > snap_grid / 2)
       n += snap_grid;

     #if DEBUG
       printf("p: %d\n", p);
       printf("m: %d\n", m);
       printf("m > snap_grid / 2: %d\n", (m > snap_grid / 2));
       printf("n: %d\n", n);
       printf("n*s: %d\n", n*sign);
     #endif

       return(sign*n);

     #if 0 /* working snap code, crude, slow */
       int interm;
       int final;
       int power;
       int itop;

       power = snap_grid;
       itop = input / power;
       interm = abs(input % power);

       if (interm > 0 && interm < snap_grid/2) {
         interm = 0;
       } else if (interm >= snap_grid/2 && interm <= snap_grid) {
         interm = snap_grid;
       }

       if (input >= 0) {
         final = itop*snap_grid+interm;
       } else if (input < 0) {
         final = itop*snap_grid-interm;
       }

       return(final);
     #endif

     }

          Defines :
          snap_grid,
           -- m_basic.c - fix_y(),
           -- m_basic.c - fix_x(),
           -- m_basic.c - SCREENtoWORLD().

     }

Function SCREENtoWORLD()
========================

 -- Function: SCREENtoWORLD w_current mx my x y

     <<m_basic.c : SCREENtoWORLD()>>=
     void
     SCREENtoWORLD(TOPLEVEL *w_current, int mx, int my, int *x, int *y)
     {
       if (w_current->snap) {
         *x = snap_grid(w_current, mil_x(w_current, mx));
         *y = snap_grid(w_current, mil_y(w_current, my));
       } else {
         *x = mil_x(w_current, mx);
         *y = mil_y(w_current, my);
       }

     #if 0
       *x = mil_x(w_current, mx);
       *y = mil_y(w_current, my);
     #endif

     }

          Defines :
          .

          Uses :
          mil_x,  -- m_basic.c - mil_x().
          mil_y,  -- m_basic.c - mil_y().
          snap_grid,  -- m_basic.c - snap_grid().

     }

Function SCREENabs()
====================

 -- Function: SCREENabs w_current val

     <<m_basic.c : SCREENabs()>>=
     /* returns screen coords */
     int
     SCREENabs(TOPLEVEL *w_current, int val)
     {
       double fs,f0,f1,f;

       double i;
       int j;

       f0 = w_current->page_current->left;
       f1 = w_current->page_current->right;
       fs = w_current->width;
       f = w_current->width / (f1 - f0);
       i = f * (double)(val);

     #ifdef HAS_RINT
       j = rint(i);
     #else
       j = i;
     #endif

       return(j);

     }

          Defines :
          .

     }

Function WORLDabs()
===================

 -- Function: WORLDabs w_current val

     <<m_basic.c : WORLDabs()>>=
     /* returns world coords */
     int
     WORLDabs(TOPLEVEL *w_current, int val)
     {
       double fw0,fw1,fw,fval;

       double i;
       int j;

       fw1 = w_current->page_current->right;
       fw0 = w_current->page_current->left;
       fw  = w_current->width;
       fval = val;
       i = fval * (fw1 - fw0) / fw;

       /* i -= mil_x_tw2;
          i = ((i) / 100 ) * 100; I don't think we need this
          i += mil_x_tw1;*/

     #ifdef HAS_RINT
       j = rint(i);
     #else
       j = i;
     #endif

       return(j);
     }

          Defines :
          .

     }

Function set_window()
=====================

 -- Function: set_window w_current page xmin xmax ymin ymax

     <<m_basic.c : set_window()>>=
     void set_window(TOPLEVEL *w_current, PAGE *page,
                     int xmin, int xmax, int ymin, int ymax)
     {
       double fs,f0,f1;
       double fw0,fw1,fw;

       page->left   = xmin;
       page->right  = xmax;
       page->top    = ymin;
       page->bottom = ymax;

       /* now do the constant setups */

       /* pix_x */
       f0 = page->left;
       f1 = page->right;
       fs = w_current->width;
       page->to_screen_x_constant = fs / (f1 - f0);

       /* pix_y */
       f0 = page->top;
       f1 = page->bottom;
       fs = w_current->height;
       page->to_screen_y_constant = fs / (f1 - f0);

       /* mil_x */
       fw1 = page->right;
       fw0 = page->left;
       fw  = w_current->width;
       page->to_world_x_constant = (fw1 - fw0) / fw;

       /* mil_y */
       fw1 = page->bottom;
       fw0 = page->top;
       fw  = w_current->height;
       page->to_world_y_constant = (fw1 - fw0) / fw;
     }

          Defines :
          .

          Uses :
          mil_x,  -- m_basic.c - mil_x().
          mil_y,  -- m_basic.c - mil_y().
          pix_x,  -- m_basic.c - pix_x().
          pix_y,  -- m_basic.c - pix_y().

     }

Function fix_x()
================

 -- Function: fix_x w_current in

     <<m_basic.c : fix_x()>>=
     /* fix_x and fix_y are used for grid snap */
     int
     fix_x(TOPLEVEL *w_current, int in)
     {
       int value;
       int ret;

       if (in > w_current->width) {
         in = w_current->width;
       }

       if (!w_current->snap)
       return(in);

       value = mil_x(w_current, in);

       ret = pix_x(w_current, snap_grid(w_current, value));
       return(ret);
     }

          Defines :
          .

          Uses :
          fix_y,  -- m_basic.c - fix_y().
          mil_x,  -- m_basic.c - mil_x().
          pix_x,  -- m_basic.c - pix_x().
          snap_grid,  -- m_basic.c - snap_grid().

     }

Function fix_y()
================

 -- Function: fix_y w_current in

     <<m_basic.c : fix_y()>>=
     int
     fix_y(TOPLEVEL *w_current, int in)
     {
       int value;
       int ret;

       if (in > w_current->height) {
         in = w_current->height;
       }

       if (!w_current->snap)
       return(in);

       value = mil_y(w_current, in);
       ret = pix_y(w_current, snap_grid(w_current, value));
       return(ret);
     }

          Defines :
          fix_y,
           -- m_basic.c - fix_x().

          Uses :
          mil_y,  -- m_basic.c - mil_y().
          pix_y,  -- m_basic.c - pix_y().
          snap_grid,  -- m_basic.c - snap_grid().

     }

Function on_snap()
==================

 -- Function: on_snap val

     <<m_basic.c : on_snap()>>=
     /* returns 0 if point (x) is snapped */
     /* returns something if point (x) is not snapped */
     /* unused for now */
     int
     on_snap(int val)
     {
       return( (val / 100)*100 - val);
     }

          Defines :
          .

     }

Function SCREENencode_halfspace()
=================================

 -- Function: SCREENencode_halfspace w_current point halfspace

     <<m_basic.c : HALFSPACE and sPOINT typedefs()>>=
     typedef struct st_halfspace HALFSPACE;
     typedef struct st_point sPOINT;

     struct st_halfspace {
       int left; /* these are booleans */
       int top;
       int right;
       int bottom;
     };

     struct st_point {
             int x, y;
     };

     <<m_basic.c : SCREENencode_halfspace()>>=
     /* encode_halfspace and clip are part of the cohen-sutherland clipping */
     /* algorithm.  They are used to determine if an object is visible or not */

     /* halfspace must be allocated before this is called */
     static void
     SCREENencode_halfspace(TOPLEVEL *w_current, sPOINT *point, HALFSPACE *halfspace)
     {
       halfspace->left = point->x < 0;
       halfspace->right = point->x > w_current->width;
       halfspace->bottom = point->y > w_current->height;
       halfspace->top = point->y < 0;
     }

          Defines :
          SCREENencode_halfspace,
           -- m_basic.c - SCREENclip_change().

          Uses :
          visible,  -- m_basic.c - visible().

     }

Function WORLDencode_halfspace()
================================

 -- Function: WORLDencode_halfspace w_current point halfspace

     <<m_basic.c : WORLDencode_halfspace()>>=
     /* halfspace must be allocated before this is called */
     static void
     WORLDencode_halfspace(TOPLEVEL *w_current, sPOINT *point, HALFSPACE *halfspace)
     {
       halfspace->left = point->x < w_current->page_current->left;
       halfspace->right = point->x > w_current->page_current->right;
       halfspace->bottom = point->y > w_current->page_current->bottom;
       halfspace->top = point->y < w_current->page_current->top;
     }

          Defines :
          WORLDencode_halfspace,
           -- m_basic.c - clip_nochange().

     }

Function SCREENclip_change()
============================

 -- Function: SCREENclip_change w_current x1 y1 x2 y2

     <<m_basic.c : SCREENclip_change()>>=
     int
     SCREENclip_change(TOPLEVEL *w_current,int *x1, int *y1, int *x2, int *y2)
     {
       HALFSPACE half1, half2;
       HALFSPACE tmp_half;
       sPOINT tmp_point;
       sPOINT point1, point2;
       float slope;
       int in1, in2, done;
       int visible;
       int w_l, w_t, w_r, w_b;

       point1.x = *x1;
       point1.y = *y1;
       point2.x = *x2;
       point2.y = *y2;

       w_l = 0;
       w_t = 0;
       w_r = w_current->width;
       w_b = w_current->height;

       done = FALSE;
       visible = FALSE;

       do {
         SCREENencode_halfspace(w_current, &point1, &half1);
         SCREENencode_halfspace(w_current, &point2, &half2);

     #if DEBUG
         printf("starting loop\n");
         printf("1 %d %d %d %d\n", half1.left, half1.top, half1.right, half1.bottom);
         printf("2 %d %d %d %d\n", half2.left, half2.top, half2.right, half2.bottom);
     #endif

         in1 = (!half1.left) &&
           (!half1.top) &&
           (!half1.right) &&
           (!half1.bottom);

         in2 = (!half2.left) &&
           (!half2.top) &&
           (!half2.right) &&
           (!half2.bottom);

         if (in1 && in2) { /* trivally accept */
           done = TRUE;
           visible = TRUE;
         } else if ( ((half1.left && half2.left) ||
                      (half1.right && half2.right)) ||
                     ((half1.top && half2.top) ||
                      (half1.bottom && half2.bottom)) ) {
           done = TRUE; /* trivially reject */
           visible = FALSE;
         } else { /* at least one point outside */
           if (in1) {
             tmp_half = half1;
             half1 = half2;
             half2 = tmp_half;

             tmp_point = point1;
             point1 = point2;
             point2 = tmp_point;
           }

           if (point2.x == point1.x) { /* vertical line */
             if (half1.top) {
               point1.y = w_t;
             } else if (half1.bottom) {
               point1.y = w_b;
             }
           } else { /* not a vertical line */

                                     /* possible fix for alpha core dumping */
                                     /* assume the object is visible */
             if ((point2.x - point1.x) == 0) {
               return(TRUE);
             }

             slope = (float) (point2.y - point1.y) /
               (float) (point2.x - point1.x);

                                     /* possible fix for alpha core dumping */
                                     /* assume the object is visible */
             if (slope == 0.0) {
               return(TRUE);
             }

             if (half1.left) {
               point1.y = point1.y +
                 (w_l - point1.x) * slope;
               point1.x = w_l;
             } else if (half1.right) {
               point1.y = point1.y +
                 (w_r - point1.x) * slope;
               point1.x = w_r;
             } else if (half1.bottom) {
               point1.x = point1.x +
                 (w_b - point1.y) / slope;
               point1.y = w_b;
             } else if (half1.top) {
               point1.x = point1.x +
                 (w_t - point1.y) / slope;
               point1.y = w_t;
             }
           } /* end of not a vertical line */
         } /* end of at least one outside */
       } while (!done);

       /*printf("after: %d %d %d %d\n", point1.x, point1.y, point2.x, point2.y);*/
       *x1 = point1.x;
       *y1 = point1.y;
       *x2 = point2.x;
       *y2 = point2.y;
       return(visible);
     }

          Defines :
          .

          Uses :
          SCREENencode_halfspace,  -- m_basic.c - SCREENencode_halfspace().
          visible,  -- m_basic.c - visible().

     }

Function clip_nochange()
========================

 -- Function: clip_nochange w_current x1 y1 x2 y2

     <<m_basic.c : clip_nochange()>>=
     int
     clip_nochange(TOPLEVEL *w_current,int x1, int y1, int x2, int y2)
     {
       HALFSPACE half1, half2;
       HALFSPACE tmp_half;
       sPOINT tmp_point;
       sPOINT point1, point2;
       float slope;
       int in1, in2, done;
       int visible;
       int w_l, w_t, w_r, w_b;

       point1.x = x1;
       point1.y = y1;
       point2.x = x2;
       point2.y = y2;

       /*printf("before: %d %d %d %d\n", x1, y1, x2, y2);*/

       w_l = w_current->page_current->left;
       w_t = w_current->page_current->top;
       w_r = w_current->page_current->right;
       w_b = w_current->page_current->bottom;

       done = FALSE;
       visible = FALSE;

       do {
         WORLDencode_halfspace(w_current, &point1, &half1);
         WORLDencode_halfspace(w_current, &point2, &half2);

     #if DEBUG
         printf("starting loop\n");
         printf("1 %d %d %d %d\n", half1.left, half1.top, half1.right, half1.bottom);
         printf("2 %d %d %d %d\n", half2.left, half2.top, half2.right, half2.bottom);
     #endif

         in1 = (!half1.left) &&
           (!half1.top) &&
           (!half1.right) &&
           (!half1.bottom);

         in2 = (!half2.left) &&
           (!half2.top) &&
           (!half2.right) &&
           (!half2.bottom);

         if (in1 && in2) { /* trivally accept */
           done = TRUE;
           visible = TRUE;
         } else if ( ((half1.left && half2.left) ||
                      (half1.right && half2.right)) ||
                     ((half1.top && half2.top) ||
                      (half1.bottom && half2.bottom)) ) {
           done = TRUE; /* trivially reject */
           visible = FALSE;
         } else { /* at least one point outside */
           if (in1) {
             tmp_half = half1;
             half1 = half2;
             half2 = tmp_half;

             tmp_point = point1;
             point1 = point2;
             point2 = tmp_point;
           }

           if (point2.x == point1.x) { /* vertical line */
             if (half1.top) {
               point1.y = w_t;
             } else if (half1.bottom) {
               point1.y = w_b;
             }
           } else { /* not a vertical line */

                                     /* possible fix for alpha core dumping */
                                     /* assume the object is visible */
             if ((point2.x - point1.x) == 0) {
               return(TRUE);
             }

             slope = (float) (point2.y - point1.y) /
               (float) (point2.x - point1.x);

                                     /* possible fix for alpha core dumping */
                                     /* assume the object is visible */
             if (slope == 0.0) {
               return(TRUE);
             }

             if (half1.left) {
               point1.y = point1.y +
                 (w_l - point1.x) * slope;
               point1.x = w_l;
             } else if (half1.right) {
               point1.y = point1.y +
                 (w_r - point1.x) * slope;
               point1.x = w_r;
             } else if (half1.bottom) {
               point1.x = point1.x +
                 (w_b - point1.y) / slope;
               point1.y = w_b;
             } else if (half1.top) {
               point1.x = point1.x +
                 (w_t - point1.y) / slope;
               point1.y = w_t;
             }
           } /* end of not a vertical line */
         } /* end of at least one outside */
       } while (!done);

       return(visible);
     }

          Defines :
          clip_nochange,
           -- m_basic.c - visible().

          Uses :
          visible,  -- m_basic.c - visible().
          WORLDencode_halfspace,  -- m_basic.c - WORLDencode_halfspace().

     }

Function visible()
==================

 -- Function: visible w_current wleft wtop wright wbottom

     <<m_basic.c : visible()>>=
     /* This is a generic routine which checks to see if the bounding box is */
     /* visible on the screen */
     /* o_circle and o_box are the only one that uses this routine */
     int
     visible(TOPLEVEL *w_current, int wleft, int wtop, int wright, int wbottom)
     {
       int visible=FALSE;

       /* don't do object clipping if this is false */
       if (!w_current->object_clipping) {
         return(TRUE);
       }

       visible = clip_nochange(w_current, wleft, wtop, wright, wtop);

     #if DEBUG
       printf("vis1 %d\n", visible);
     #endif

       if (!visible) {
         visible = clip_nochange(w_current, wleft, wbottom, wright, wbottom);
       } else {
         return(visible);
       }

     #if DEBUG
       printf("vis2 %d\n", visible);
     #endif

       if (!visible) {
         visible = clip_nochange(w_current, wleft, wtop, wleft, wbottom);
       } else {
         return(visible);
       }

     #if DEBUG
       printf("vis3 %d\n", visible);
     #endif

       if (!visible) {
         visible = clip_nochange(w_current, wright, wtop, wright, wbottom);
       } else {
         return(visible);
       }

     #if DEBUG
       printf("vis4 %d\n", visible);
     #endif

     #if DEBUG
       printf("%d %d %d\n", wleft, w_current->page_current->top, wright);
       printf("%d %d %d\n", wtop, w_current->page_current->top, wbottom);
       printf("%d %d %d\n", wleft, w_current->page_current->right, wright);
       printf("%d %d %d\n", wtop, w_current->page_current->bottom, wbottom);
     #endif

       /* now check to see if bounding box encompasses the entire viewport */
       if (w_current->page_current->left >= wleft &&
           w_current->page_current->left <= wright  &&
           w_current->page_current->top <= wtop &&
           w_current->page_current->top >= wbottom ) {
         /*w_current->page_current->right >= wleft &&
           w_current->page_current->right <= wright &&
           w_current->page_current->bottom <= wtop &&
           w_current->page_current->bottom >= wbottom ) {*/
         visible = 1;
       }

     #if DEBUG
       printf("vis5 %d\n", visible);
     #endif

       return(visible);
     }

          Defines :
          visible,
           -- m_basic.c - SCREENencode_halfspace(),
           -- m_basic.c - clip_nochange(),
           -- m_basic.c - SCREENclip_change().

          Uses :
          clip_nochange,  -- m_basic.c - clip_nochange().

     }

Function rotate_point()
=======================

 -- Function: rotate_point x y angle newx newy

     <<m_basic.c : rotate_point()>>=
     void
     rotate_point(int x, int y, int angle, int *newx, int *newy)
     {
       double costheta, sintheta;
       double rad;

       rad = angle*M_PI/180;

       costheta = cos(rad);
       sintheta = sin(rad);

       *newx = x * costheta - y * sintheta;
       *newy = x * sintheta + y * costheta;
     }

          Defines :
          .

     }

Function rotate_point_90()
==========================

 -- Function: rotate_point_90 x y angle newx newy

     <<m_basic.c : rotate_point_90()>>=
     /* allows for rotations of increments 90 degrees only */
     void
     rotate_point_90(int x, int y, int angle, int *newx, int *newy)
     {
       double costheta=1;
       double sintheta=0;

       /* I could have used sine/cosine for this, but I want absolute
        * accuracy */
       switch(angle) {

         case(0):
           *newx = x;
           *newy = y;
           return;
           break;

         case(90):
           costheta = 0;
           sintheta = 1;
           break;

         case(180):
           costheta = -1;
           sintheta = 0;
           break;

         case(270):
           costheta = 0;
           sintheta = -1;
           break;
       }

       *newx = x * costheta - y * sintheta;
       *newy = x * sintheta + y * costheta;

     #if 0 /* fixed rotation */

       *newx = -y ;
       *newy = x ;
     #endif

     }

          Defines :
          .

     }

Function PAPERSIZEtoWORLD()
===========================

 -- Function: PAPERSIZEtoWORLD width height border right bottom

     <<m_basic.c : PAPERSIZEtoWORLD()>>=
     /* support landscape only for now */
     /* fixed aspect ratio */
     void
     PAPERSIZEtoWORLD(int width, int height, int border, int *right, int *bottom)
     {
       float aspect;

       aspect = (float) width / (float) height;

     #if DEBUG
       printf("%f\n", aspect);
     #endif

       if (aspect < 1.333333333) {
         /* is this rint really needed? */
     #ifdef HAS_RINT
         *right = (int) rint(width+border +
                             ((height+border)*1.33333333 - (width+border)));
     #else
         *right = (int) width+border +
           ((height+border)*1.33333333 - (width+border));
     #endif
         *bottom = height+border;
       } else {
         *right = (int) width+border;
         *bottom = (int) height+border + ((width+border)/1.33333333 - (height+border));
       }

     #if DEBUG
       aspect = (float) *right / (float) *bottom;
       printf("%f\n", aspect);
     #endif

     }

          Defines :
          .

     }

Function return_zoom_number()
=============================

 -- Function: return_zoom_number zoom_factor

     <<m_basic.c : return_zoom_number()>>=
     /* this function returns the # of zoom's we have done, since zoom_factor */
     /* is actually the magnification level */
     #if 0 /* no longer used at all */
     int
     return_zoom_number(int zoom_factor)
     {
       double check=0;
       double factor;
       int i=0;

       if (zoom_factor != 0) {
         factor = zoom_factor;
         check = pow(2, i);
         while( check != factor && check < factor) {
           i++;
           check = pow(2, i);
         }
       } else {
         return(0);
       }

       return(i);

     #if 0 /* delete eventually */
       if (zoom_factor > 0) {
         return(log(zoom_factor)+2);
         /* return(log(zoom_factor+1));*/
       } else {
         return(1);
       }
     #endif
     }
     #endif

          Defines :
          .

     }

Function round_5_2_1()
======================

 -- Function: round_5_2_1 unrounded

     <<m_basic.c : round_5_2_1()>>=
     /* rounds for example 1235 to 1000, 670 to 500, 0.234 to 0.2 ...
     int would be enough if there are no numbers smaller 1 (hw)*/
     double
     round_5_2_1(double unrounded)
     {
       int digits;
       double betw_1_10;

       /*only using the automatic cast */
       digits = log10(unrounded);
       /* creates numbers between 1 and 10 */
       betw_1_10 = unrounded / pow(10,digits);

       if (betw_1_10 < 1.5) {
         return(pow(10,digits));
       }
       if (betw_1_10 > 1.4 && betw_1_10 < 3.5 ) {
         return(2*pow(10,digits));
       }
       if (betw_1_10 > 3.4 && betw_1_10 < 7.5 ) {
         return(5*pow(10,digits));
       }
       else {
         return(10*pow(10,digits));
       }
     }

          Defines :
          .

     }