/*
 *	$Source: /u1/Xr/src/Xrlib/Intrinsic/RCS/calc.c,v $
 *	$Header: calc.c,v 1.1 86/12/17 09:07:46 swick Exp $
 */

#ifndef lint
static char *rcsid_calc_c = "$Header: calc.c,v 1.1 86/12/17 09:07:46 swick Exp $";
#endif	lint

#include <Xr/xr-copyright.h>

/* $Header: calc.c,v 1.1 86/12/17 09:07:46 swick Exp $ */
/* Copyright 1986, Hewlett-Packard Company */
/* Copyright 1986, Massachussetts Institute of Technology */

static char rcsid[] = "$Header: calc.c,v 1.1 86/12/17 09:07:46 swick Exp $";
/*************************************<+>*************************************
 *****************************************************************************
 **
 **   File:        calc.c
 **
 **   Project:     X-ray Toolbox
 **
 **   Description: This file contains the set of point and rectangle
 **                calculation routines.
 **
 **
 **   ------------------------ MODIFICATION RECORD   ------------------------
 *
 * $Log:	calc.c,v $
 * Revision 1.1  86/12/17  09:07:46  swick
 * Initial revision
 * 
 * Revision 7.0  86/11/13  08:17:59  08:17:59  rick ()
 * Final QA release
 * 
 * Revision 6.0  86/11/10  15:21:06  15:21:06  rick ()
 * QA #2 release
 * 
 * Revision 5.1  86/11/07  14:01:18  14:01:18  rick ()
 * Added the copyright message.
 * 
 * Revision 5.0  86/10/28  08:21:50  08:21:50  rick ()
 * QA #1.1 release
 * 
 * Revision 4.0  86/10/20  12:07:28  12:07:28  rick ()
 * QA 1 release
 * 
 * Revision 3.2  86/10/17  12:22:27  12:22:27  rick ()
 * Linted
 * 
 * Revision 3.1  86/10/16  11:19:43  11:19:43  rick ()
 * Added register variables.
 * 
 * Revision 3.0  86/10/02  15:56:39  15:56:39  rick ()
 *  Alpha release set to 3.0
 * 
 * Revision 2.0  86/09/16  07:55:55  07:55:55  rick ()
 * *** empty log message ***
 * 
 * Revision 1.1  86/09/03  13:34:51  13:34:51  rick ()
 * Initial revision
 * 
 *
 *****************************************************************************
 *************************************<+>*************************************/


#include <X/Xlib.h>
#include <Xr/defs.h>
#include <Xr/types.h>



/*************************************<->*************************************
 *
 *   Procedures:
 *   -----------
 *    Refer to XrRectangle(3Xr) man page.
 *
 *
 *   Descriptions:
 *   -----------
 *     XrSetRect     -  Set the fields of a rectangle.
 *
 *     XrSetPtRect   -  Find an assign the coordinates of a rectangle.
 *
 *     XrCopyRect    -  Copy one rectangle into another.
 *
 *     XrOffsetRect  -  Move a rectangle by the offset values.
 *
 *     XrInsetRect   -  Change the size of a rectangle.
 *
 *     XrSectRect    -  Find the intersection of 2 rectangles.
 *
 *     XrUnionRect   -  Find the union of 2 rectangles.
 *
 *     XrPtInRect    -  Is the point in the rectangle?
 *
 *     XrPt2Rect     -  Find the rectangle enclosing 2 points.
 *
 *     XrEqualRect   -  Compare 2 rectangle for equality.
 *
 *     XrEmptyRect   -  Is the rectangle empty?
 *
 *
 *   Inputs:
 *   ------
 *     Refer to XrRectangle(3Xr) man page.
 *
 * 
 *   Outputs:
 *   -------
 *     Refer to XrRectangle(3Xr) man page.
 *
 *
 *   Procedures Called
 *   -----------------
 *     None.
 *
 *************************************<->***********************************/


XrSetRect (rect, x, y, width, height)
register RECTANGLE * rect;
INT16 x;
INT16 y;
INT16 width;
INT16 height;

{
   rect -> x = x;
   rect -> y = y;
   rect -> width = width;
   rect -> height = height;
}


XrSetPtRect (rect, topLeft, botRight)
register RECTANGLE * rect;
register POINT     * topLeft;
register POINT     * botRight;

{
   rect -> x = topLeft -> x;
   rect -> y = topLeft -> y;
   rect -> width = botRight -> x - topLeft -> x + 1;
   rect -> height = botRight -> y - topLeft -> y + 1;
}


XrCopyRect (srcRect, dstRect)
register RECTANGLE * srcRect;
register RECTANGLE * dstRect;

{
   dstRect -> x = srcRect -> x;
   dstRect -> y = srcRect -> y;
   dstRect -> width = srcRect -> width;
   dstRect -> height = srcRect -> height;
}


XrOffsetRect (rect, dx, dy)
RECTANGLE * rect;
INT16 dx;
INT16 dy;

{
   rect -> x += dx;
   rect -> y += dy;
}


XrInsetRect (rect, dx, dy)
register RECTANGLE * rect;
register INT16 dx;
register INT16 dy;

{
   rect -> x += dx;
   rect -> y += dy;
   rect -> width -= (dx + dx);
   rect -> height -= (dy + dy);
}


XrSectRect (srcRectA, srcRectB, dstRect)
register RECTANGLE * srcRectA;
register RECTANGLE * srcRectB;
register RECTANGLE * dstRect;

{
   register int srcABot, srcBBot;
   register int srcARight, srcBRight;

   srcABot = srcRectA -> y + srcRectA -> height - 1;
   srcBBot = srcRectB -> y + srcRectB -> height - 1;
   srcARight = srcRectA -> x + srcRectA -> width - 1;
   srcBRight = srcRectB -> x + srcRectB -> width - 1;

   if (srcRectA -> x >= srcRectB -> x) dstRect -> x = srcRectA -> x;
   else dstRect -> x = srcRectB -> x;

   if (srcRectA -> y > srcRectB -> y) dstRect -> y = srcRectA -> y;
   else dstRect -> y = srcRectB -> y;

   if (srcARight >= srcBRight) dstRect->width = srcBRight - dstRect->x + 1;
   else dstRect->width = srcARight - dstRect->x + 1;

   if (srcABot > srcBBot) dstRect->height = srcBBot - dstRect->y + 1; 
   else dstRect->height = srcABot - dstRect->y + 1;

   if (XrEmptyRect(dstRect))
   {
      XrSetRect(dstRect, 0, 0, 0, 0);
      return(FALSE);
   }

   return(TRUE);
}


XrUnionRect (srcRectA, srcRectB, dstRect)
register RECTANGLE * srcRectA;
register RECTANGLE * srcRectB;
register RECTANGLE * dstRect;

{
   register int srcABot, srcBBot;
   register int srcARight, srcBRight;

   srcABot = srcRectA -> y + srcRectA -> height - 1;
   srcBBot = srcRectB -> y + srcRectB -> height - 1;
   srcARight = srcRectA -> x + srcRectA -> width - 1;
   srcBRight = srcRectB -> x + srcRectB -> width - 1;

   if (srcRectA -> x >= srcRectB -> x) dstRect -> x = srcRectB -> x;
   else dstRect -> x = srcRectA -> x;

   if (srcRectA -> y >= srcRectB -> y) dstRect -> y = srcRectB -> y;
   else dstRect -> y = srcRectA -> y;

   if (srcABot >= srcBBot) dstRect->height = srcABot - dstRect->y + 1;
   else dstRect->height = srcBBot - dstRect->y + 1;

   if (srcARight >= srcBRight) dstRect->width = srcARight - dstRect->x + 1;
   else dstRect->width = srcBRight - dstRect->x + 1;

}


XrPtInRect (pt, r)
register POINT * pt;
register RECTANGLE * r;

{
   if (pt->x < r->x || pt->x >= r->x + r->width ||
       pt->y < r->y || pt->y >= r->y + r->height)
      return (FALSE);

   return (TRUE);
}


XrPt2Rect (ptA, ptB, dstRect)
register POINT * ptA;
register POINT * ptB;
register RECTANGLE * dstRect;

{
   if (ptA->x > ptB->x)
   {
      dstRect->x = ptB->x;
      dstRect->width = ptA->x - ptB->x + 1;
   }
   else
   {
      dstRect->x = ptA->x;
      dstRect->width = ptB->x - ptA->x + 1;
   }


   if (ptA->y > ptB->y)
   {
      dstRect->y = ptB->y;
      dstRect->height = ptA->y - ptB->y + 1;
   }
   else
   {
      dstRect->y = ptA->y;
      dstRect->height = ptB->y - ptA->y + 1;
   }
}


XrEqualRect (rectA, rectB)
register RECTANGLE * rectA;
register RECTANGLE * rectB;

{
   if (rectA->x == rectB->x && rectA->y == rectB->y &&
       rectA->width == rectB->width && rectA->height == rectB->height)
      return (TRUE);

   return (FALSE);
}


XrEmptyRect (r)
register RECTANGLE * r;

{
   if (r->width <= 0 || r->height <= 0)
      return (TRUE);

   return (FALSE);
}



/*************************************<->*************************************
 *
 *   Procedures:
 *   -----------
 *    Refer to XrPoint(3Xr) man page.
 *
 *
 *   Descriptions:
 *   -----------
 *     XrAddPt     -  Add two points together.
 *
 *     XrSubPt     -  Subtract to points.
 *
 *     XrSetPt     -  Set a point's fields.
 *
 *     XrOffsetPt  -  Add an offset to a point.
 *
 *     XrCopyPt    -  Copy one point into another.
 *
 *     XrEqualPt   -  Return TRUE if the two points are equal.
 *
 *
 *   Inputs:
 *   ------
 *     Refer to XrPoint(3Xr) man page.
 *
 * 
 *   Outputs:
 *   -------
 *     Refer to XrPoint(3Xr) man page.
 *
 *
 *   Procedures Called
 *   -----------------
 *     None.
 *
 *************************************<->***********************************/


XrAddPt (srcPt, dstPt)
POINT * srcPt;
POINT * dstPt;

{
   dstPt->x += srcPt->x;
   dstPt->y += srcPt->y;
}


XrSubPt (srcPt, dstPt)
POINT * srcPt;
POINT * dstPt;

{
   dstPt->x -= srcPt->x;
   dstPt->y -= srcPt->y;
}


XrSetPt (pt, x, y)
POINT * pt;
INT16 x;
INT16 y;

{
   pt->x = x;
   pt->y = y;
}


XrOffsetPt (srcPt, dx, dy)
POINT * srcPt;
INT16   dx;
INT16   dy;

{
   srcPt -> x += dx;
   srcPt -> y += dy;
}


XrCopyPt (srcPt, dstPt)
POINT * srcPt;
POINT * dstPt;

{
   dstPt->x = srcPt->x;
   dstPt->y = srcPt->y;
}


XrEqualPt (ptA, ptB)
register POINT * ptA;
register POINT * ptB;

{
   if (ptA->x == ptB->x && ptA->y == ptB->y)
      return (TRUE);
   return (FALSE);
}
