[comp.sources.x] v12i028: tgif, Part12/23

william@CS.UCLA.EDU (William Cheng) (03/14/91)

Submitted-by: william@CS.UCLA.EDU (William Cheng)
Posting-number: Volume 12, Issue 28
Archive-name: tgif/part12

---------------------------------> cut here <---------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 12 (of 23)."
# Contents:  rect.c ruler.c
# Wrapped by william@oahu on Wed Mar  6 09:57:36 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'rect.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rect.c'\"
else
echo shar: Extracting \"'rect.c'\" \(37131 characters\)
sed "s/^X//" >'rect.c' <<'END_OF_FILE'
X/*
X * Author:	William Chia-Wei Cheng (william@cs.ucla.edu)
X *
X * Copyright (C) 1990, 1991, William Cheng.
X */
X#ifndef lint
Xstatic char RCSid[] =
X      "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/rect.c,v 2.0 91/03/05 12:48:11 william Exp $";
X#endif
X
X#include <X11/Xlib.h>
X#include <math.h>
X#include "const.h"
X#include "types.h"
X
X#include "arc.e"
X#include "poly.e"
X#include "setup.e"
X#include "spline.e"
X
Xint BBoxIntersect (Rect1, Rect2)
X   struct BBRec	Rect1, Rect2;
X{
X   if (Rect1.ltx < Rect2.ltx)
X      if (Rect1.lty < Rect2.lty)
X         return (Rect1.rbx >= Rect2.ltx && Rect1.rby >= Rect2.lty);
X      else
X         return (Rect1.rbx >= Rect2.ltx && Rect1.lty <= Rect2.rby);
X   else
X      if (Rect1.lty < Rect2.lty)
X         return (Rect1.ltx <= Rect2.rbx && Rect1.rby >= Rect2.lty);
X      else
X         return (Rect1.ltx <= Rect2.rbx && Rect1.lty <= Rect2.rby);
X}
X
Xint PointInBBox (X, Y, Rect)
X   int	X, Y;
X   struct BBRec	Rect;
X{
X   return (X >= Rect.ltx && Y >= Rect.lty && X <= Rect.rbx && Y <= Rect.rby);
X}
X
Xint PointInPolygon (X, Y, NumPts, V)
X   int		X, Y, NumPts;
X   XPoint	* V;
X{
X   register double	x1, x2, y1, y2;
X   double		m, y_int;
X   int			n, count = 0;
X
X   x2 = (double)V[0].x;
X   y2 = (double)V[0].y;
X   for (n = 0; n < NumPts-1; n++)
X   {
X      x1 = x2;
X      y1 = y2;
X      x2 = (double)V[n+1].x;
X      y2 = (double)V[n+1].y;
X      if (x2 == x1 && X == x1)
X      {
X         if (Y <= min(y1,y2)) count++;
X         continue;
X      }
X      if (x2 > x1)
X      {
X         if (X >= x2 || X < x1) continue;
X      }
X      else
X      {
X         if (X > x1 || X <= x2) continue;
X      }
X
X      m = (y1 - y2) / (x1 - x2);
X      y_int = m * X + (y1 - m * x1);
X      if (Y <= y_int) count++;
X   }
X   return (count & 0x1);
X}
X
Xint PointInPoly (X, Y, NumPts, V, W)
X   int		X, Y, NumPts, W;
X   XPoint	* V;
X{
X   register double	x1, x2, y1, y2;
X   double		m, m1, b, b1, x_int, y_int;
X   int			n;
X
X   x2 = (double)V[0].x;
X   y2 = (double)V[0].y;
X   for (n = 0; n < NumPts-1; n++)
X   {
X      x1 = x2;
X      y1 = y2;
X      x2 = (double)V[n+1].x;
X      y2 = (double)V[n+1].y;
X      if (x2 >= x1)
X      {
X         if (X < x1-W || X > x2+W) continue;
X      }
X      else
X      {
X         if (X < x2-W || X > x1+W) continue;
X      }
X      if (y2 >= y1)
X      {
X         if (Y < y1-W || Y > y2+W) continue;
X      }
X      else
X      {
X         if (Y < y2-W || Y > y1+W) continue;
X      }
X
X      if (x1 == x2 || y1 == y2)
X         return (TRUE);
X      else
X      {
X         m = (y1 - y2) / (x1 - x2);
X         b = y1 - m * x1;
X         m1 = (x2 - x1) / (y1 - y2);
X         b1 = Y - m1 * X;
X         x_int = (b1 - b) / (m - m1);
X         y_int = m * x_int + b;
X         if (sqrt ((double)(x_int-X)*(x_int-X)+(y_int-Y)*(y_int-Y)) <= (double)W)
X            return (TRUE);
X      }
X   }
X   return (FALSE);
X}
X
Xint FindGoodBox (X, Y, BoxObj)
X   int			X, Y;
X   struct ObjRec	* BoxObj;
X   /* X and Y are absolute coordinates */
X{
X   struct BBRec	bbox;
X   int		w;
X
X   if (BoxObj->detail.b->fill != 0) return (TRUE);
X
X   w = (widthOfLine[BoxObj->detail.b->width]+3) << zoomScale;
X   bbox.ltx = BoxObj->obbox.ltx + w;
X   bbox.lty = BoxObj->obbox.lty + w;
X   bbox.rbx = BoxObj->obbox.rbx - w;
X   bbox.rby = BoxObj->obbox.rby - w;
X   return (!PointInBBox (X, Y, bbox));
X}
X
Xint FindGoodRCBox (X, Y, RCBoxObj)
X   int			X, Y;
X   struct ObjRec	* RCBoxObj;
X   /* X and Y are absolute coordinates */
X{
X   register struct BBRec	* obbox;
X   register struct BBRec	bbox;
X   int				w, r;
X
X   if (RCBoxObj->detail.b->fill != 0) return (TRUE);
X
X   r = RCBoxObj->detail.rcb->radius;
X   w = (widthOfLine[RCBoxObj->detail.rcb->width]+3) << zoomScale;
X   obbox = &(RCBoxObj->obbox);
X
X   bbox.ltx = obbox->ltx + w; bbox.lty = obbox->lty + r;
X   bbox.rbx = obbox->rbx - w; bbox.rby = obbox->rby - r;
X
X   if (PointInBBox (X, Y, bbox))
X      return (FALSE);
X   else
X   {
X      bbox.ltx = obbox->ltx + r; bbox.lty = obbox->lty + w;
X      bbox.rbx = obbox->rbx - r; bbox.rby = obbox->rby - w;
X      return (!PointInBBox (X, Y, bbox));
X   }
X}
X
Xint FindGoodOval (X, Y, OvalObj)
X   int			X, Y;
X   struct ObjRec	* OvalObj;
X   /* X and Y are absolute coordinates */
X{
X   struct OvalRec	* oval_ptr = OvalObj->detail.o;
X   int			w, ltx, lty, rbx, rby, delta;
X   double		cx, cy, rx, ry, tmp_x, tmp_y;
X   double		x1 = 0.0, x2 = 0.0, y1 = 0.0, y2 = 0.0;
X   int			fill = oval_ptr->fill;
X
X   ltx = OvalObj->obbox.ltx; lty = OvalObj->obbox.lty;
X   rbx = OvalObj->obbox.rbx; rby = OvalObj->obbox.rby;
X
X   cx = (ltx + rbx) / 2; cy = (lty + rby) / 2;
X   rx = (rbx - ltx) / 2; ry = (rby - lty) / 2;
X
X   if (rx >= ry)
X   {  /* flat oval */
X      tmp_y = sqrt (fabs ((double)(ry*ry*(1-(X-cx)*(X-cx)/rx/rx))));
X      y1 = cy - tmp_y;
X      y2 = cy + tmp_y;
X      delta = (int)(3.0*(ry/rx));
X   }
X   else
X   {  /* tall oval */
X      tmp_x = sqrt (fabs ((double)(rx*rx*(1-(Y-cy)*(Y-cy)/ry/ry))));
X      x1 = cx - tmp_x;
X      x2 = cx + tmp_x;
X      delta = (int)(3.0*(rx/ry));
X   }
X
X   if (fill != NONEPAT)
X   {
X      if (rx >= ry)
X      {  /* flat oval */
X         if (Y >= y1 && y2 >= Y) return (TRUE);
X      }
X      else
X      {  /* tall oval */
X         if (X >= x1 && x2 >= X) return (TRUE);
X      }
X   }
X   w = (widthOfLine[oval_ptr->width]+3+delta) << zoomScale;
X   if (rx >= ry)
X      return ((fabs ((double)(Y-y1)) <= w) || (fabs ((double)(Y-y2)) <= w));
X   else
X      return ((fabs ((double)(X-x1)) <= w) || (fabs ((double)(X-x2)) <= w));
X}
X
Xint FindGoodPoly (X, Y, PolyObj)
X   int			X, Y;
X   struct ObjRec	* PolyObj;
X   /* X and Y are absolute coordinates */
X{
X   int			w, n;
X   XPoint		* v;
X   struct PolyRec	* poly_ptr;
X
X   poly_ptr = PolyObj->detail.p;
X   w = (arrowHeadH[poly_ptr->width]+3) << zoomScale;
X   if (poly_ptr->curved == LT_SPLINE)
X      return (PointInSplinePoly (X, Y, poly_ptr, w));
X   else
X   {
X      if (poly_ptr->fill != NONEPAT)
X      {
X         n = poly_ptr->n;
X         v = poly_ptr->vlist;
X         v[n].x = v[0].x; v[n].y = v[0].y;
X         if (PointInPolygon (X, Y, n+1, v))
X            return (TRUE);
X      }
X      return (PointInPoly (X, Y, poly_ptr->n, poly_ptr->vlist, w));
X   }
X}
X
Xint FindGoodPolygon (X, Y, PolygonObj)
X   int			X, Y;
X   struct ObjRec	* PolygonObj;
X   /* X and Y are absolute coordinates */
X{
X   int			w;
X   struct PolygonRec	* polygon_ptr;
X
X   polygon_ptr = PolygonObj->detail.g;
X   w = (widthOfLine[polygon_ptr->width]+3) << zoomScale;
X   if (polygon_ptr->curved == LT_SPLINE)
X      return (PointInSplinePolygon (X, Y, polygon_ptr, w));
X   else
X   {
X      if (polygon_ptr->fill != NONEPAT)
X         if (PointInPolygon (X, Y, polygon_ptr->n, polygon_ptr->vlist))
X            return (TRUE);
X      return (PointInPoly (X, Y, polygon_ptr->n, polygon_ptr->vlist, w));
X   }
X}
X
Xstatic
Xint PointInFlatPie (X,Y,dir,angle,ov_int_y1,ov_int_y2,rad_int_y1,rad_int_y2)
X   int		X, Y, dir, angle;
X   double	ov_int_y1, ov_int_y2, rad_int_y1, rad_int_y2;
X{
X   switch (dir)
X   {
X      case ARC_CCW:
X         switch ((angle+360)%360)
X         {
X            case 0:
X               if (ov_int_y2 > rad_int_y1)
X               {
X                  if (Y>=rad_int_y2 && rad_int_y1>=Y) return (TRUE);
X               }
X               else if (ov_int_y2 > rad_int_y2)
X               {
X                  if (Y>=rad_int_y2 && ov_int_y2>=Y) return (TRUE);
X               }
X               break;
X            case 90:
X               if (ov_int_y1 < rad_int_y2)
X               {
X                  if (Y>=rad_int_y2 && rad_int_y1>=Y) return (TRUE);
X               }
X               else if (ov_int_y1 < rad_int_y1)
X               {
X                  if (Y>=ov_int_y1 && rad_int_y1>=Y) return (TRUE);
X               }
X               break;
X            case 180:
X               if (ov_int_y1 < rad_int_y1)
X               {
X                  if (Y>=rad_int_y1 && rad_int_y2>=Y) return (TRUE);
X               }
X               else if (ov_int_y1 < rad_int_y2)
X               {
X                  if (Y>=ov_int_y1 && rad_int_y2>=Y) return (TRUE);
X               }
X               break;
X            case 270:
X               if (ov_int_y2 > rad_int_y2)
X               {
X                  if (Y>=rad_int_y1 && rad_int_y2>=Y) return (TRUE);
X               }
X               else if (ov_int_y2 > rad_int_y1)
X               {
X                  if (Y>=rad_int_y1 && ov_int_y2>=Y) return (TRUE);
X               }
X               break;
X         }
X         break;
X      case ARC_CW:
X         switch ((angle+360)%360)
X         {
X            case 0:
X               if (ov_int_y1 < rad_int_y1)
X               {
X                  if (Y>=rad_int_y1 && rad_int_y2>=Y) return (TRUE);
X               }
X               else if (ov_int_y1 < rad_int_y2)
X               {
X                  if (Y>=ov_int_y1 && rad_int_y2>=Y) return (TRUE);
X               }
X               break;
X            case 90:
X               if (ov_int_y1 < rad_int_y2)
X               {
X                  if (Y>=rad_int_y2 && rad_int_y1>=Y) return (TRUE);
X               }
X               else if (ov_int_y1 < rad_int_y1)
X               {
X                  if (Y>=ov_int_y1 && rad_int_y1>=Y) return (TRUE);
X               }
X               break;
X            case 180:
X               if (ov_int_y2 > rad_int_y1)
X               {
X                  if (Y>=rad_int_y2 && rad_int_y1>=Y) return (TRUE);
X               }
X               else if (ov_int_y2 > rad_int_y2)
X               {
X                  if (Y>=rad_int_y2 && ov_int_y2>=Y) return (TRUE);
X               }
X               break;
X            case 270:
X               if (ov_int_y2 > rad_int_y2)
X               {
X                  if (Y>=rad_int_y1 && rad_int_y2>=Y) return (TRUE);
X               }
X               else if (ov_int_y2 > rad_int_y1)
X               {
X                  if (Y>=rad_int_y1 && ov_int_y2>=Y) return (TRUE);
X               }
X               break;
X         }
X         break;
X   }
X   return (FALSE);
X}
X
Xstatic
Xint PointInTallPie (X,Y,dir,angle,ov_int_x1,ov_int_x2,rad_int_x1,rad_int_x2)
X   int		X, Y, dir, angle;
X   double	ov_int_x1, ov_int_x2, rad_int_x1, rad_int_x2;
X{
X   switch (dir)
X   {
X      case ARC_CCW:
X         switch ((angle+360)%360)
X         {
X            case 0:
X               if (ov_int_x2 > rad_int_x2)
X               {
X                  if (X>=rad_int_x1 && rad_int_x2>=X) return (TRUE);
X               }
X               else if (ov_int_x2 > rad_int_x1)
X               {
X                  if (X>=rad_int_x1 && ov_int_x2>=X) return (TRUE);
X               }
X               break;
X            case 90:
X               if (ov_int_x2 > rad_int_x1)
X               {
X                  if (X>=rad_int_x2 && rad_int_x1>=X) return (TRUE);
X               }
X               else if (ov_int_x2 > rad_int_x2)
X               {
X                  if (X>=rad_int_x2 && ov_int_x2>=X) return (TRUE);
X               }
X               break;
X            case 180:
X               if (ov_int_x1 < rad_int_x2)
X               {
X                  if (X>=rad_int_x2 && rad_int_x1>=X) return (TRUE);
X               }
X               else if (ov_int_x1 < rad_int_x1)
X               {
X                  if (X>=rad_int_x1 && ov_int_x1>=X) return (TRUE);
X               }
X               break;
X            case 270:
X               if (ov_int_x1 < rad_int_x1)
X               {
X                  if (X>=rad_int_x1 && rad_int_x2>=X) return (TRUE);
X               }
X               else if (ov_int_x1 < rad_int_x2)
X               {
X                  if (X>=ov_int_x1 && rad_int_x2>=X) return (TRUE);
X               }
X               break;
X         }
X         break;
X      case ARC_CW:
X         switch ((angle+360)%360)
X         {
X            case 0:
X               if (ov_int_x2 > rad_int_x2)
X               {
X                  if (X>=rad_int_x1 && rad_int_x2>=X) return (TRUE);
X               }
X               else if (ov_int_x2 > rad_int_x1)
X               {
X                  if (X>=rad_int_x1 && ov_int_x2>=X) return (TRUE);
X               }
X               break;
X            case 90:
X               if (ov_int_x1 < rad_int_x1)
X               {
X                  if (X>=rad_int_x1 && rad_int_x2>=X) return (TRUE);
X               }
X               else if (ov_int_x1 < rad_int_x2)
X               {
X                  if (X>=rad_int_x2 && ov_int_x1>=X) return (TRUE);
X               }
X               break;
X            case 180:
X               if (ov_int_x1 < rad_int_x2)
X               {
X                  if (X>=rad_int_x2 && rad_int_x1>=X) return (TRUE);
X               }
X               else if (ov_int_x1 < rad_int_x1)
X               {
X                  if (X>=ov_int_x1 && rad_int_x1>=X) return (TRUE);
X               }
X               break;
X            case 270:
X               if (ov_int_x2 > rad_int_x1)
X               {
X                  if (X>=rad_int_x2 && rad_int_x1>=X) return (TRUE);
X               }
X               else if (ov_int_x2 > rad_int_x2)
X               {
X                  if (X>=rad_int_x2 && ov_int_x2>=X) return (TRUE);
X               }
X               break;
X         }
X         break;
X   }
X   return (FALSE);
X}
X
Xstatic
Xint XInPieRange (X, dir, angle, cx, rx)
X   int		X, dir, angle;
X   double	cx, rx;
X{
X   switch (dir)
X   {
X      case ARC_CCW:
X         switch ((angle+360)%360)
X         {
X            case 0:
X            case 90: return (X>=cx && cx+rx>=X);
X
X            case 180:
X            case 270: return (X>=cx-rx && cx>=X);
X         }
X         break;
X      case ARC_CW:
X         switch ((angle+360)%360)
X         {
X            case 0:
X            case 270: return (X>=cx && cx+rx>=X);
X
X            case 90:
X            case 180: return (X>=cx-rx && cx>=X);
X         }
X         break;
X   }
X}
X
Xstatic
Xint YInPieRange (Y, dir, angle, cy, ry)
X   int		Y, dir, angle;
X   double	cy, ry;
X{
X   switch (dir)
X   {
X      case ARC_CCW:
X         switch ((angle+360)%360)
X         {
X            case 0:
X            case 270: return (Y>=cy && cy+ry>=Y);
X
X            case 90:
X            case 180: return (Y>=cy-ry && cy>=Y);
X         }
X         break;
X      case ARC_CW:
X         switch ((angle+360)%360)
X         {
X            case 0:
X            case 90: return (Y>=cy-ry && cy>=Y);
X
X            case 180:
X            case 270: return (Y>=cy && cy+ry>=Y);
X         }
X         break;
X   }
X}
X
Xint FindGoodArc (X, Y, ArcObj)
X   int			X, Y;
X   struct ObjRec	* ArcObj;
X   /* X and Y are absolute coordinates */
X{
X   struct ArcRec	* arc_ptr = ArcObj->detail.a;
X   int			w, ltx, lty, rbx, rby, delta;
X   double		cx, cy, rx, ry, tmp_x, tmp_y, x = 0.0, y = 0.0;
X   double		ov_int_x1 = 0.0, ov_int_x2 = 0.0;
X   double		ov_int_y1 = 0.0, ov_int_y2 = 0.0;
X   double		rad_int_x1 = 0.0, rad_int_x2 = 0.0;
X   double		rad_int_y1 = 0.0, rad_int_y2 = 0.0;
X   int			fill = arc_ptr->fill;
X   int			arc_x1, arc_y1, arc_x2, arc_y2, theta1, theta2;
X   int			pass_theta1, just_pass_theta1, angle, dir;
X
X   ltx = arc_ptr->ltx; lty = arc_ptr->lty;
X   rbx = ltx+arc_ptr->w; rby = lty+arc_ptr->h;
X   rx = arc_ptr->w/2; ry = arc_ptr->h/2;
X
X   cx = arc_ptr->xc; cy = arc_ptr->yc;
X   arc_x1 = arc_ptr->x1; arc_y1 = arc_ptr->y1;
X   dir = arc_ptr->dir;
X
X   theta1 = (int)(arc_ptr->angle1)/64;
X   theta2 = theta1 + (int)(arc_ptr->angle2)/64;
X   ArcRealX2Y2 (arc_ptr, &arc_x2, &arc_y2);
X
X   if (theta2 < -180) theta2 += 360;
X   if (theta2 > 180) theta2 -= 360;
X
X   if (theta1 < 0) theta1 += 360;
X   if (theta2 <= 0) theta2 += 360;
X
X   if (rx >= ry)
X   {  /* flat oval */
X      tmp_y = sqrt (fabs ((double)(ry*ry*(1-(X-cx)*(X-cx)/rx/rx))));
X      ov_int_y1 = cy - tmp_y;
X      ov_int_y2 = cy + tmp_y;
X      delta = (int)(3.0*(ry/rx));
X   }
X   else
X   {  /* tall oval */
X      tmp_x = sqrt (fabs ((double)(rx*rx*(1-(Y-cy)*(Y-cy)/ry/ry))));
X      ov_int_x1 = cx - tmp_x;
X      ov_int_x2 = cx + tmp_x;
X      delta = (int)(3.0*(rx/ry));
X   }
X
X   w = (widthOfLine[arc_ptr->width]+3+delta) << zoomScale;
X   if (rx >= ry)
X   {  /* flat oval */
X      rad_int_y1 = cy + (X-cx)*(arc_y1-cy)/(arc_x1-cx);
X      rad_int_y2 = cy + (X-cx)*(arc_y2-cy)/(arc_x2-cx);
X   }
X   else
X   {  /* tall oval */
X      rad_int_x1 = cx + (Y-cy)*(arc_x1-cx)/(arc_y1-cy);
X      rad_int_x2 = cx + (Y-cy)*(arc_x2-cx)/(arc_y2-cy);
X   }
X   if (dir == ARC_CCW)
X   {
X      angle = 0;
X      pass_theta1 = FALSE;
X      just_pass_theta1 = FALSE;
X      while (angle < theta2 || !pass_theta1)
X      {
X         if (angle >= theta1 && !pass_theta1)
X         {
X            pass_theta1 = TRUE;
X            just_pass_theta1 = TRUE;
X            if (theta2 > theta1 && angle >= theta2)
X            {  /* theta1 and theta2 are in the same quadrant */
X               if (fill != NONEPAT)
X               {
X                  if (rx >= ry)
X                  {
X                     if (PointInFlatPie (X, Y, dir, angle, ov_int_y1,
X                           ov_int_y2, rad_int_y1, rad_int_y2));
X                        return (TRUE);
X                  }
X                  else
X                  {
X                     if (PointInTallPie (X, Y, dir, angle, ov_int_x1,
X                           ov_int_x2, rad_int_x1, rad_int_x2));
X                        return (TRUE);
X                  }
X               }
X               if (rx >= ry)
X               {
X                  switch ((angle+360)%360)
X                  {
X                     case 0:
X                     case 270:
X                        return (X>=arc_x1 && arc_x2>=X &&
X                              (fabs ((double)(Y-ov_int_y2)) <= w));
X                     case 90:
X                     case 180:
X                        return (X>=arc_x2 && arc_x1>=X &&
X                              (fabs ((double)(Y-ov_int_y1)) <= w));
X                  }
X               }
X               else
X               {
X                  switch ((angle+360)%360)
X                  {
X                     case 0:
X                     case 90:
X                        return (Y>=arc_y2 && arc_y1>=Y &&
X                              (fabs ((double)(X-ov_int_x2)) <= w));
X                     case 180:
X                     case 270:
X                        return (Y>=arc_y1 && arc_y2>=Y &&
X                              (fabs ((double)(X-ov_int_x1)) <= w));
X                  }
X               }
X            }
X            if (theta2 < theta1) angle -= 360;
X         }
X         if (just_pass_theta1)
X         {
X            just_pass_theta1 = FALSE;
X            if (rx >= ry)
X            {
X               switch ((angle+360)%360)
X               {
X                  case 0: y = cy; break;
X                  case 90: y = cy-ry; break;
X                  case 180: y = cy; break;
X                  case 270: y = cy+ry; break;
X               }
X               if (fill != NONEPAT)
X               {
X                  if (XInPieRange (X, dir, angle, cx, rx) &&
X                        PointInFlatPie (X, Y, dir, angle, ov_int_y1,
X                        ov_int_y2, rad_int_y1, y))
X                     return (TRUE);
X               }
X               switch ((angle+360)%360)
X               {
X                  case 0:
X                     if (X>=arc_x1 && cx+rx>=X &&
X                           (fabs ((double)(Y-ov_int_y2)) <= w))
X                        return (TRUE);
X                     break;
X                  case 90:
X                     if (X>=cx && arc_x1>=X &&
X                           (fabs ((double)(Y-ov_int_y1)) <= w))
X                        return (TRUE);
X                     break;
X                  case 180:
X                     if (X>=cx-rx && arc_x1>=X &&
X                           (fabs ((double)(Y-ov_int_y1)) <= w))
X                        return (TRUE);
X                     break;
X                  case 270:
X                     if (X>=arc_x1 && cx>=X &&
X                           (fabs ((double)(Y-ov_int_y2)) <= w))
X                        return (TRUE);
X                     break;
X               }
X            }
X            else
X            {
X               switch ((angle+360)%360)
X               {
X                  case 0: x = cx+rx; break;
X                  case 90: x = cx; break;
X                  case 180: x = cx-rx; break;
X                  case 270: x = cx; break;
X               }
X               if (fill != NONEPAT)
X               {
X                  if (YInPieRange (Y, dir, angle, cy, ry) &&
X                        PointInTallPie (X, Y, dir, angle, ov_int_x1,
X                        ov_int_x2, rad_int_x1, x))
X                     return (TRUE);
X               }
X               switch ((angle+360)%360)
X               {
X                  case 0:
X                     if (Y>=cy && arc_y1>=Y &&
X                           (fabs ((double)(X-ov_int_x1)) <= w))
X                        return (TRUE);
X                     break;
X                  case 90:
X                     if (Y>=cy-ry && arc_y1>=Y &&
X                           (fabs ((double)(X-ov_int_x2)) <= w))
X                        return (TRUE);
X                     break;
X                  case 180:
X                     if (Y>=arc_y1 && cy>=Y &&
X                           (fabs ((double)(X-ov_int_x1)) <= w))
X                        return (TRUE);
X                     break;
X                  case 270:
X                     if (Y>=arc_y1 && cy+ry>=Y &&
X                           (fabs ((double)(X-ov_int_x2)) <= w))
X                        return (TRUE);
X                     break;
X               }
X            }
X         }
X         else if (pass_theta1)
X         {  /* see if point is in the quadrant */
X            if (rx >= ry)
X            {
X               if (XInPieRange (X, dir, angle, cx, rx))
X               {
X                  if (fill != NONEPAT)
X                  {
X                     switch ((angle+360)%360)
X                     {
X                        case 90:
X                        case 180:
X                           if (Y>=ov_int_y1 && cy>=Y) return (TRUE);
X                           break;
X
X                        case 0:
X                        case 270:
X                           if (Y>=cy && ov_int_y2>=Y) return (TRUE);
X                           break;
X                     }
X                  }
X                  switch ((angle+360)%360)
X                  {
X                     case 0:
X                     case 270:
X                        if (fabs ((double)(Y-ov_int_y2)) <= w) return (TRUE);
X                        break;
X                     case 90:
X                     case 180:
X                        if (fabs ((double)(Y-ov_int_y1)) <= w) return (TRUE);
X                        break;
X                  }
X               }
X            }
X            else
X            {
X               if (YInPieRange (Y, dir, angle, cy, ry))
X               {
X                  if (fill != NONEPAT)
X                  {
X                     switch ((angle+360)%360)
X                     {
X                        case 0:
X                        case 90:
X                           if (X>=cx && ov_int_x2>=X) return (TRUE);
X                           break;
X
X                        case 180:
X                        case 270:
X                           if (X>=ov_int_x1 && cx>=X) return (TRUE);
X                           break;
X                     }
X                  }
X                  switch ((angle+360)%360)
X                  {
X                     case 0:
X                     case 90:
X                        if (fabs ((double)(X-ov_int_x2)) <= w) return (TRUE);
X                        break;
X                     case 180:
X                     case 270:
X                        if (fabs ((double)(X-ov_int_x1)) <= w) return (TRUE);
X                        break;
X                  }
X               }
X            }
X         }
X         angle = (angle == 360) ? 0 : (angle+90);
X      }
X      if (rx >= ry)
X      {
X         switch ((angle+360)%360)
X         {
X            case 0: y = cy+ry; break;
X            case 180: y = cy-ry; break;
X
X            case 90:
X            case 270: y = cy; break;
X         }
X         if (fill != NONEPAT)
X         {
X            if (XInPieRange (X, dir, angle, cx, rx) &&
X                  PointInFlatPie (X, Y, dir, angle, ov_int_y1, ov_int_y2,
X                  y, rad_int_y2))
X               return (TRUE);
X         }
X         switch ((angle+360)%360)
X         {
X            case 0:
X               if (X>=cx && arc_x2>=X &&
X                     (fabs ((double)(Y-ov_int_y2)) <= w))
X                  return (TRUE);
X               break;
X            case 90:
X               if (X>=arc_x2 && cx+rx>=X &&
X                     (fabs ((double)(Y-ov_int_y1)) <= w))
X                  return (TRUE);
X               break;
X            case 180:
X               if (X>=arc_x2 && cx>=X &&
X                     (fabs ((double)(Y-ov_int_y1)) <= w))
X                  return (TRUE);
X               break;
X            case 270:
X               if (X>=cx-rx && arc_x2>=X &&
X                     (fabs ((double)(Y-ov_int_y2)) <= w))
X                  return (TRUE);
X               break;
X         }
X      }
X      else
X      {
X         switch ((angle+360)%360)
X         {
X            case 0:
X            case 180: x = cx; break;
X
X            case 90: x = cx+rx; break;
X            case 270: x = cx-rx; break;
X         }
X         if (fill != NONEPAT)
X         {
X            if (YInPieRange (Y, dir, angle, cy, ry) &&
X                  PointInTallPie (X, Y, dir, angle, ov_int_x1, ov_int_x2,
X                  x, rad_int_x2))
X               return (TRUE);
X         }
X         switch ((angle+360)%360)
X         {
X            case 0:
X               if (Y>=arc_y2 && cy+ry>=Y &&
X                     (fabs ((double)(X-ov_int_x2)) <= w))
X                  return (TRUE);
X               break;
X            case 90:
X               if (Y>=arc_y2 && cy>=Y &&
X                     (fabs ((double)(X-ov_int_x2)) <= w))
X                  return (TRUE);
X               break;
X            case 180:
X               if (Y>=cy-ry && arc_y2>=Y &&
X                     (fabs ((double)(X-ov_int_x1)) <= w))
X                  return (TRUE);
X               break;
X            case 270:
X               if (Y>=cy && arc_y2>=Y &&
X                     (fabs ((double)(X-ov_int_x1)) <= w))
X                  return (TRUE);
X               break;
X         }
X      }
X   }
X   else
X   {
X      angle = 360;
X      pass_theta1 = FALSE;
X      just_pass_theta1 = FALSE;
X      while (angle > theta2 || !pass_theta1)
X      {
X         if (angle <= theta1 && !pass_theta1)
X         {
X            pass_theta1 = TRUE;
X            just_pass_theta1 = TRUE;
X            if (theta2 < theta1 && angle <= theta2)
X            {  /* theta1 and theta2 are in the same quadrant */
X               if (fill != NONEPAT)
X               {
X                  if (rx >= ry)
X                  {
X                     if (PointInFlatPie (X, Y, dir, angle, ov_int_y1,
X                           ov_int_y2, rad_int_y1, rad_int_y2));
X                        return (TRUE);
X                  }
X                  else
X                  {
X                     if (PointInTallPie (X, Y, dir, angle, ov_int_x1,
X                           ov_int_x2, rad_int_x1, rad_int_x2));
X                        return (TRUE);
X                  }
X               }
X               if (rx >= ry)
X               {
X                  switch ((angle+360)%360)
X                  {
X                     case 0:
X                     case 90:
X                        return (X>=arc_x1 && arc_x2>=X &&
X                              (fabs ((double)(Y-ov_int_y1)) <= w));
X                     case 180:
X                     case 270:
X                        return (X>=arc_x2 && arc_x1>=X &&
X                              (fabs ((double)(Y-ov_int_y2)) <= w));
X                  }
X               }
X               else
X               {
X                  switch ((angle+360)%360)
X                  {
X                     case 0:
X                     case 270:
X                        return (Y>=arc_y1 && arc_y2>=Y &&
X                              (fabs ((double)(X-ov_int_x2)) <= w));
X                     case 90:
X                     case 180:
X                        return (Y>=arc_y2 && arc_y1>=Y &&
X                              (fabs ((double)(X-ov_int_x1)) <= w));
X                  }
X               }
X            }
X            if (theta2 > theta1) angle += 360;
X         }
X         if (just_pass_theta1)
X         {
X            just_pass_theta1 = FALSE;
X            if (rx >= ry)
X            {
X               switch ((angle+360)%360)
X               {
X                  case 0: y = cy; break;
X                  case 90: y = cy-ry; break;
X                  case 180: y = cy; break;
X                  case 270: y = cy+ry; break;
X               }
X               if (fill != NONEPAT)
X               {
X                  if (XInPieRange (X, dir, angle, cx, rx) &&
X                        PointInFlatPie (X, Y, dir, angle, ov_int_y1,
X                        ov_int_y2, rad_int_y1, y))
X                     return (TRUE);
X               }
X               switch ((angle+360)%360)
X               {
X                  case 0:
X                     if (X>=arc_x1 && cx+rx>=X &&
X                           (fabs ((double)(Y-ov_int_y1)) <= w))
X                        return (TRUE);
X                     break;
X                  case 90:
X                     if (X>=arc_x1 && cx>=X &&
X                           (fabs ((double)(Y-ov_int_y1)) <= w))
X                        return (TRUE);
X                     break;
X                  case 180:
X                     if (X>=cx-rx && arc_x1>=X &&
X                           (fabs ((double)(Y-ov_int_y2)) <= w))
X                        return (TRUE);
X                     break;
X                  case 270:
X                     if (X>=cx && arc_x1>=X &&
X                           (fabs ((double)(Y-ov_int_y2)) <= w))
X                        return (TRUE);
X                     break;
X               }
X            }
X            else
X            {
X               switch ((angle+360)%360)
X               {
X                  case 0: x = cx+rx; break;
X                  case 90: x = cx; break;
X                  case 180: x = cx-rx; break;
X                  case 270: x = cx; break;
X               }
X               if (fill != NONEPAT)
X               {
X                  if (YInPieRange (Y, dir, angle, cy, ry) &&
X                        PointInTallPie (X, Y, dir, angle, ov_int_x1,
X                        ov_int_x2, rad_int_x1, x))
X                     return (TRUE);
X               }
X               switch ((angle+360)%360)
X               {
X                  case 0:
X                     if (Y>=arc_y1 && cy>=Y &&
X                           (fabs ((double)(X-ov_int_x2)) <= w))
X                        return (TRUE);
X                     break;
X                  case 90:
X                     if (Y>=cy-ry && arc_y1>=Y &&
X                           (fabs ((double)(X-ov_int_x1)) <= w))
X                        return (TRUE);
X                     break;
X                  case 180:
X                     if (Y>=arc_y1 && cy+ry>=Y &&
X                           (fabs ((double)(X-ov_int_x1)) <= w))
X                        return (TRUE);
X                     break;
X                  case 270:
X                     if (Y>=cy && arc_y1>=Y &&
X                           (fabs ((double)(X-ov_int_x2)) <= w))
X                        return (TRUE);
X                     break;
X               }
X            }
X         }
X         else if (pass_theta1)
X         {  /* see if point is in the quadrant */
X            if (rx >= ry)
X            {
X               if (XInPieRange (X, dir, angle, cx, rx))
X               {
X                  if (fill != NONEPAT)
X                  {
X                     switch ((angle+360)%360)
X                     {
X                        case 0:
X                        case 90:
X                           if (Y>=ov_int_y1 && cy>=Y) return (TRUE);
X                           break;
X      
X                        case 180:
X                        case 270:
X                           if (Y>=cy && ov_int_y2>=Y) return (TRUE);
X                           break;
X                     }
X                  }
X                  switch ((angle+360)%360)
X                  {
X                     case 0:
X                     case 90:
X                        if (fabs ((double)(Y-ov_int_y1)) <= w) return (TRUE);
X                        break;
X                     case 180:
X                     case 270:
X                        if (fabs ((double)(Y-ov_int_y2)) <= w) return (TRUE);
X                        break;
X                  }
X               }
X            }
X            else
X            {
X               if (YInPieRange (Y, dir, angle, cy, ry))
X               {
X                  if (fill != NONEPAT)
X                  {
X                     switch ((angle+360)%360)
X                     {
X                        case 0:
X                        case 270:
X                           if (X>=cx && ov_int_x2>=X) return (TRUE);
X                           break;
X                        case 90:
X                        case 180: 
X                           if (X>=ov_int_x1 && cx>=X) return (TRUE);
X                           break;
X                     }
X                  }
X                  switch ((angle+360)%360)
X                  {
X                     case 0:
X                     case 270:
X                        if (fabs ((double)(X-ov_int_x2)) <= w) return (TRUE);
X                        break;
X                     case 90:
X                     case 180:
X                        if (fabs ((double)(X-ov_int_x1)) <= w) return (TRUE);
X                        break;
X                  }
X               }
X            }
X         }
X         angle = (angle == 0) ? 360 : (angle-90);
X      }
X      if (rx >= ry)
X      {
X         switch ((angle+360)%360)
X         {
X            case 0: y = cy-ry; break;
X            case 180: y = cy+ry; break;
X
X            case 90:
X            case 270: y = cy; break;
X         }
X         if (fill != NONEPAT)
X         {
X            if (XInPieRange (X, dir, angle, cx, rx) &&
X                  PointInFlatPie (X, Y, dir, angle, ov_int_y1, ov_int_y2,
X                  y, rad_int_y2))
X               return (TRUE);
X         }
X         switch ((angle+360)%360)
X         {
X            case 0:
X               if (X>=cx && arc_x2>=X &&
X                     (fabs ((double)(Y-ov_int_y1)) <= w))
X                  return (TRUE);
X               break;
X            case 90:
X               if (X>=cx-rx && arc_x2>=X &&
X                     (fabs ((double)(Y-ov_int_y1)) <= w))
X                  return (TRUE);
X               break;
X            case 180:
X               if (X>=arc_x2 && cx>=X &&
X                     (fabs ((double)(Y-ov_int_y2)) <= w))
X                  return (TRUE);
X               break;
X            case 270:
X               if (X>=arc_x2 && cx+rx>=X &&
X                     (fabs ((double)(Y-ov_int_y2)) <= w))
X                  return (TRUE);
X               break;
X         }
X      }
X      else
X      {
X         switch ((angle+360)%360)
X         {
X            case 0:
X            case 180: x = cx; break;
X
X            case 90: x = cx-rx; break;
X            case 270: x = cx+rx; break;
X         }
X         if (fill != NONEPAT)
X         {
X            if (YInPieRange (Y, dir, angle, cy, ry) &&
X                  PointInTallPie (X, Y, dir, angle, ov_int_x1, ov_int_x2,
X                  x, rad_int_x2))
X               return (TRUE);
X         }
X         switch ((angle+360)%360)
X         {
X            case 0:
X               if (Y>=cy-ry && arc_y2>=Y &&
X                     (fabs ((double)(X-ov_int_x2)) <= w))
X                  return (TRUE);
X               break;
X            case 90:
X               if (Y>=arc_y2 && cy>=Y &&
X                     (fabs ((double)(X-ov_int_x1)) <= w))
X                  return (TRUE);
X               break;
X            case 180:
X               if (Y>=arc_y2 && cy+ry>=Y &&
X                     (fabs ((double)(X-ov_int_x1)) <= w))
X                  return (TRUE);
X               break;
X            case 270:
X               if (Y>=cy && arc_y2>=Y &&
X                     (fabs ((double)(X-ov_int_x2)) <= w))
X                  return (TRUE);
X               break;
X         }
X      }
X   }
X   return (FALSE);
X}
X
Xint FindGoodObj (X, Y, FirstObj)
X   int			X, Y;
X   struct ObjRec	* FirstObj;
X   /* X and Y are absolute coordinates */
X{
X   register struct ObjRec	* obj_ptr;
X
X   for (obj_ptr = FirstObj; obj_ptr != NULL; obj_ptr = obj_ptr->next)
X      if (X >= obj_ptr->bbox.ltx-3 && X <= obj_ptr->bbox.rbx+3 &&
X            Y >= obj_ptr->bbox.lty-3 && Y <= obj_ptr->bbox.rby+3)
X      {
X         switch (obj_ptr->type)
X         {
X            case OBJ_TEXT: return (TRUE);
X            case OBJ_XBM: return (TRUE);
X            case OBJ_BOX:
X               if (FindGoodBox (X, Y, obj_ptr)) return (TRUE);
X               break;
X            case OBJ_RCBOX:
X               if (FindGoodRCBox (X, Y, obj_ptr)) return (TRUE);
X               break;
X            case OBJ_OVAL:
X               if (FindGoodOval (X, Y, obj_ptr)) return (TRUE);
X               break;
X            case OBJ_POLY:
X               if (FindGoodPoly (X, Y, obj_ptr)) return (TRUE);
X               break;
X            case OBJ_POLYGON:
X               if (FindGoodPolygon (X, Y, obj_ptr)) return (TRUE);
X               break;
X            case OBJ_ARC:
X               if (FindGoodArc (X, Y, obj_ptr)) return (TRUE);
X               break;
X
X            case OBJ_GROUP:
X            case OBJ_SYM:
X            case OBJ_ICON:
X               if (FindGoodObj (X, Y, obj_ptr->detail.r->first)) return (TRUE);
X               break;
X         }
X      }
X   return (FALSE);
X}
END_OF_FILE
if test 37131 -ne `wc -c <'rect.c'`; then
    echo shar: \"'rect.c'\" unpacked with wrong size!
fi
# end of 'rect.c'
fi
if test -f 'ruler.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ruler.c'\"
else
echo shar: Extracting \"'ruler.c'\" \(4658 characters\)
sed "s/^X//" >'ruler.c' <<'END_OF_FILE'
X/*
X * Author:	William Chia-Wei Cheng (william@cs.ucla.edu)
X *
X * Copyright (C) 1990, 1991, William Cheng.
X */
X#ifndef lint
Xstatic char RCSid[] =
X      "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/ruler.c,v 2.0 91/03/05 12:48:16 william Exp $";
X#endif
X
X#include <X11/Xlib.h>
X#include "const.h"
X#include "types.h"
X
X#include "font.e"
X#include "grid.e"
X#include "raster.e"
X#include "setup.e"
X
X#define INCH_H 8
X#define HALF_INCH_H 6
X#define QUARTER_INCH_H 4
X#define MIN_INCH_H 2
X
Xstatic GC	rulerGC;
X
Xstatic int	oldXOff = 0;
Xstatic int	oldYOff = 0;
X
Xvoid InitRuler ()
X{
X   XGCValues	values;
X
X   values.foreground = myFgPixel;
X   values.background = myBgPixel;
X   values.fill_style = FillSolid;
X   values.font = rulerFontPtr->fid;
X
X   rulerGC = XCreateGC (mainDisplay, mainWindow,
X         GCForeground | GCBackground | GCFillStyle | GCFont, &values);
X}
X
Xvoid CleanUpRuler ()
X{
X   XFreeGC (mainDisplay, rulerGC);
X}
X
Xvoid RedrawHRuler ()
X{
X   register int	i, pos, len, index;
X   int		inc, abs_inc, start;
X   char		s[5];
X   XEvent	ev;
X
X   XClearWindow (mainDisplay, hRuleWindow);
X
X   XSync (mainDisplay, FALSE);
X   while (XCheckWindowEvent (mainDisplay, hRuleWindow, ExposureMask, &ev)) ;
X
X   inc = xyGrid;
X   abs_inc = (xyGrid<<zoomScale);
X
X   start = ((int)(drawOrigX / abs_inc)) * abs_inc;
X   for (pos = 0, i = start; i < drawOrigX+drawWinW; i += abs_inc, pos += inc)
X   {
X      if ((i>>zoomScale) % ONE_INCH == 0)
X      {
X         index = (int)((i>>zoomScale) / ONE_INCH);
X         if (pageStyle == SLIDELAND || pageStyle == SLIDEPORT)
X            sprintf (s, "%1d", (index<<zoomScale)<<1);
X         else
X            sprintf (s, "%1d", index<<zoomScale);
X         len = strlen (s);
X         XDrawString (mainDisplay, hRuleWindow, rulerGC, pos-rulerFontWidth/2,
X               rulerW-INCH_H-rulerFontDes, s, len);
X         XDrawLine (mainDisplay, hRuleWindow, defaultGC, pos, rulerW,
X               pos, rulerW-INCH_H);
X      }
X      else if ((i>>zoomScale) % HALF_INCH == 0)
X      {
X         XDrawLine (mainDisplay, hRuleWindow, defaultGC, pos, rulerW,
X               pos, rulerW-HALF_INCH_H);
X      }
X      else if ((i>>zoomScale) % QUARTER_INCH == 0)
X      {
X         XDrawLine (mainDisplay, hRuleWindow, defaultGC, pos, rulerW,
X               pos, rulerW-QUARTER_INCH_H);
X      }
X      else
X         XDrawLine (mainDisplay, hRuleWindow, defaultGC, pos, rulerW,
X               pos, rulerW-MIN_INCH_H);
X   }
X   oldXOff = 0;
X   XDrawLine (mainDisplay, hRuleWindow, revDefaultGC, oldXOff, 0,
X         oldXOff, rulerW-1);
X}
X
Xvoid RedrawVRuler ()
X{
X   register int	i, pos, len, index;
X   int		inc, abs_inc, start;
X   char		s[5];
X   XEvent	ev;
X
X   XClearWindow (mainDisplay, vRuleWindow);
X
X   XSync (mainDisplay, FALSE);
X   while (XCheckWindowEvent (mainDisplay, vRuleWindow, ExposureMask, &ev)) ;
X
X   inc = xyGrid;
X   abs_inc = (xyGrid<<zoomScale);
X
X   start = ((int)(drawOrigY / abs_inc)) * abs_inc;
X   for (pos = 0, i = start; i < drawOrigY+drawWinH; i += abs_inc, pos += inc)
X   {
X      if ((i>>zoomScale) % ONE_INCH == 0)
X      {
X         index = (int)((i>>zoomScale) / ONE_INCH);
X         if (pageStyle == SLIDELAND || pageStyle == SLIDEPORT)
X            sprintf (s, "%1d", (index<<zoomScale)<<1);
X         else
X            sprintf (s, "%1d", index<<zoomScale);
X         len = strlen (s);
X         XDrawString (mainDisplay, vRuleWindow, rulerGC, 1,
X               pos-rulerFontHeight/2+rulerFontAsc, s, len);
X         XDrawLine (mainDisplay, vRuleWindow, defaultGC, rulerW, pos,
X               rulerW-INCH_H, pos);
X      }
X      else if ((i>>zoomScale) % HALF_INCH == 0)
X      {
X         XDrawLine (mainDisplay, vRuleWindow, defaultGC, rulerW, pos,
X               rulerW-HALF_INCH_H, pos);
X      }
X      else if ((i>>zoomScale) % QUARTER_INCH == 0)
X      {
X         XDrawLine (mainDisplay, vRuleWindow, defaultGC, rulerW, pos,
X               rulerW-QUARTER_INCH_H, pos);
X      }
X      else
X         XDrawLine (mainDisplay, vRuleWindow, defaultGC, rulerW, pos,
X               rulerW-MIN_INCH_H, pos);
X   }
X   oldYOff = 0;
X   XDrawLine (mainDisplay, vRuleWindow, revDefaultGC, 0, oldYOff,
X         rulerW-1, oldYOff);
X}
X
Xvoid MarkRulers (XOff, YOff)
X   int	XOff, YOff;
X{
X   XDrawLine (mainDisplay, hRuleWindow, revDefaultGC, oldXOff, 0,
X         oldXOff, rulerW-1);
X   XDrawLine (mainDisplay, vRuleWindow, revDefaultGC, 0, oldYOff,
X         rulerW-1, oldYOff);
X   XDrawLine (mainDisplay, hRuleWindow, revDefaultGC, XOff, 0,
X         XOff, rulerW-1);
X   XDrawLine (mainDisplay, vRuleWindow, revDefaultGC, 0, YOff,
X         rulerW-1, YOff);
X
X   oldXOff = XOff;
X   oldYOff = YOff;
X}
X
Xvoid RedrawRulers ()
X{
X   RedrawHRuler ();
X   RedrawVRuler ();
X}
END_OF_FILE
if test 4658 -ne `wc -c <'ruler.c'`; then
    echo shar: \"'ruler.c'\" unpacked with wrong size!
fi
# end of 'ruler.c'
fi
echo shar: End of archive 12 \(of 23\).
cp /dev/null ark12isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 23 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
---------------------------------> cut here <---------------------------------
-- 
Bill Cheng // UCLA Computer Science Department // (213) 206-7135
3277 Boelter Hall // Los Angeles, California 90024 // USA
william@CS.UCLA.EDU      ...!{uunet|ucbvax}!cs.ucla.edu!william

--
Dan Heller
------------------------------------------------
O'Reilly && Associates		 Z-Code Software
Senior Writer			       President
argv@ora.com			argv@zipcode.com
------------------------------------------------
General Email: argv@sun.com
Comp-sources-x stuff: comp-sources.x@uunet.uu.net