OSDN Git Service

Please enter the commit message for your changes. Lines starting
[eos/base.git] / util / src / TclTk / blt2.5 / generic / bltGrMisc.c
diff --git a/util/src/TclTk/blt2.5/generic/bltGrMisc.c b/util/src/TclTk/blt2.5/generic/bltGrMisc.c
deleted file mode 100644 (file)
index ae5656a..0000000
+++ /dev/null
@@ -1,1890 +0,0 @@
-
-/*
- * bltGrMisc.c --
- *
- *     This module implements miscellaneous routines for the BLT
- *     graph widget.
- *
- * Copyright 1993-1998 Lucent Technologies, Inc.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that the copyright notice and warranty
- * disclaimer appear in supporting documentation, and that the names
- * of Lucent Technologies any of their entities not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission.
- *
- * Lucent Technologies disclaims all warranties with regard to this
- * software, including all implied warranties of merchantability and
- * fitness.  In no event shall Lucent Technologies be liable for any
- * special, indirect or consequential damages or any damages
- * whatsoever resulting from loss of use, data or profits, whether in
- * an action of contract, negligence or other tortuous action, arising
- * out of or in connection with the use or performance of this
- * software.  
- */
-
-#include "bltGraph.h"
-#include <X11/Xutil.h>
-
-#if defined(__STDC__)
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-
-static Tk_OptionParseProc StringToPoint;
-static Tk_OptionPrintProc PointToString;
-static Tk_OptionParseProc StringToColorPair;
-static Tk_OptionPrintProc ColorPairToString;
-Tk_CustomOption bltPointOption =
-{
-    StringToPoint, PointToString, (ClientData)0
-};
-Tk_CustomOption bltColorPairOption =
-{
-    StringToColorPair, ColorPairToString, (ClientData)0
-};
-
-/* ----------------------------------------------------------------------
- * Custom option parse and print procedures
- * ----------------------------------------------------------------------
- */
-
-/*
- *----------------------------------------------------------------------
- *
- * Blt_GetXY --
- *
- *     Converts a string in the form "@x,y" into an XPoint structure
- *     of the x and y coordinates.
- *
- * Results:
- *     A standard Tcl result. If the string represents a valid position
- *     *pointPtr* will contain the converted x and y coordinates and
- *     TCL_OK is returned.  Otherwise, TCL_ERROR is returned and
- *     interp->result will contain an error message.
- *
- *----------------------------------------------------------------------
- */
-int
-Blt_GetXY(interp, tkwin, string, xPtr, yPtr)
-    Tcl_Interp *interp;
-    Tk_Window tkwin;
-    char *string;
-    int *xPtr, *yPtr;
-{
-    char *comma;
-    int result;
-    int x, y;
-
-    if ((string == NULL) || (*string == '\0')) {
-       *xPtr = *yPtr = -SHRT_MAX;
-       return TCL_OK;
-    }
-    if (*string != '@') {
-       goto badFormat;
-    }
-    comma = strchr(string + 1, ',');
-    if (comma == NULL) {
-       goto badFormat;
-    }
-    *comma = '\0';
-    result = ((Tk_GetPixels(interp, tkwin, string + 1, &x) == TCL_OK) &&
-       (Tk_GetPixels(interp, tkwin, comma + 1, &y) == TCL_OK));
-    *comma = ',';
-    if (!result) {
-       Tcl_AppendResult(interp, ": can't parse position \"", string, "\"",
-           (char *)NULL);
-       return TCL_ERROR;
-    }
-    *xPtr = x, *yPtr = y;
-    return TCL_OK;
-
-  badFormat:
-    Tcl_AppendResult(interp, "bad position \"", string, 
-            "\": should be \"@x,y\"", (char *)NULL);
-    return TCL_ERROR;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * StringToPoint --
- *
- *     Convert the string representation of a legend XY position into
- *     window coordinates.  The form of the string must be "@x,y" or
- *     none.
- *
- * Results:
- *     A standard Tcl result.  The symbol type is written into the
- *     widget record.
- *
- *----------------------------------------------------------------------
- */
-/*ARGSUSED*/
-static int
-StringToPoint(clientData, interp, tkwin, string, widgRec, offset)
-    ClientData clientData;     /* Not used. */
-    Tcl_Interp *interp;                /* Interpreter to send results back to */
-    Tk_Window tkwin;           /* Not used. */
-    char *string;              /* New legend position string */
-    char *widgRec;             /* Widget record */
-    int offset;                        /* offset to XPoint structure */
-{
-    XPoint *pointPtr = (XPoint *)(widgRec + offset);
-    int x, y;
-
-    if (Blt_GetXY(interp, tkwin, string, &x, &y) != TCL_OK) {
-       return TCL_ERROR;
-    }
-    pointPtr->x = x, pointPtr->y = y;
-    return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * PointToString --
- *
- *     Convert the window coordinates into a string.
- *
- * Results:
- *     The string representing the coordinate position is returned.
- *
- *----------------------------------------------------------------------
- */
-/*ARGSUSED*/
-static char *
-PointToString(clientData, tkwin, widgRec, offset, freeProcPtr)
-    ClientData clientData;     /* Not used. */
-    Tk_Window tkwin;           /* Not used. */
-    char *widgRec;             /* Widget record */
-    int offset;                        /* offset of XPoint in record */
-    Tcl_FreeProc **freeProcPtr;        /* Memory deallocation scheme to use */
-{
-    char *result;
-    XPoint *pointPtr = (XPoint *)(widgRec + offset);
-
-    result = "";
-    if ((pointPtr->x != -SHRT_MAX) && (pointPtr->y != -SHRT_MAX)) {
-       char string[200];
-
-       sprintf(string, "@%d,%d", pointPtr->x, pointPtr->y);
-       result = Blt_Strdup(string);
-       assert(result);
-       *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
-    }
-    return result;
-}
-
-/*LINTLIBRARY*/
-static int
-GetColorPair(interp, tkwin, fgStr, bgStr, pairPtr, allowDefault)
-    Tcl_Interp *interp;
-    Tk_Window tkwin;
-    char *fgStr, *bgStr;
-    ColorPair *pairPtr;
-    int allowDefault;
-{
-    unsigned int length;
-    XColor *fgColor, *bgColor;
-
-    length = strlen(fgStr);
-    if (fgStr[0] == '\0') {
-       fgColor = NULL;
-    } else if ((allowDefault) && (fgStr[0] == 'd') &&
-       (strncmp(fgStr, "defcolor", length) == 0)) {
-       fgColor = COLOR_DEFAULT;
-    } else {
-       fgColor = Tk_GetColor(interp, tkwin, Tk_GetUid(fgStr));
-       if (fgColor == NULL) {
-           return TCL_ERROR;
-       }
-    }
-    length = strlen(bgStr);
-    if (bgStr[0] == '\0') {
-       bgColor = NULL;
-    } else if ((allowDefault) && (bgStr[0] == 'd') &&
-       (strncmp(bgStr, "defcolor", length) == 0)) {
-       bgColor = COLOR_DEFAULT;
-    } else {
-       bgColor = Tk_GetColor(interp, tkwin, Tk_GetUid(bgStr));
-       if (bgColor == NULL) {
-           return TCL_ERROR;
-       }
-    }
-    pairPtr->fgColor = fgColor;
-    pairPtr->bgColor = bgColor;
-    return TCL_OK;
-}
-
-void
-Blt_FreeColorPair(pairPtr)
-    ColorPair *pairPtr;
-{
-    if ((pairPtr->bgColor != NULL) && (pairPtr->bgColor != COLOR_DEFAULT)) {
-       Tk_FreeColor(pairPtr->bgColor);
-    }
-    if ((pairPtr->fgColor != NULL) && (pairPtr->fgColor != COLOR_DEFAULT)) {
-       Tk_FreeColor(pairPtr->fgColor);
-    }
-    pairPtr->bgColor = pairPtr->fgColor = NULL;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * StringToColorPair --
- *
- *     Convert the color names into pair of XColor pointers.
- *
- * Results:
- *     A standard Tcl result.  The color pointer is written into the
- *     widget record.
- *
- *----------------------------------------------------------------------
- */
-/*ARGSUSED*/
-static int
-StringToColorPair(clientData, interp, tkwin, string, widgRec, offset)
-    ClientData clientData;     /* Not used. */
-    Tcl_Interp *interp;                /* Interpreter to send results back to */
-    Tk_Window tkwin;           /* Not used. */
-    char *string;              /* String representing color */
-    char *widgRec;             /* Widget record */
-    int offset;                        /* Offset of color field in record */
-{
-    ColorPair *pairPtr = (ColorPair *)(widgRec + offset);
-    ColorPair sample;
-    int allowDefault = (int)clientData;
-
-    sample.fgColor = sample.bgColor = NULL;
-    if ((string != NULL) && (*string != '\0')) {
-       int nColors;
-       char **colors;
-       int result;
-
-       if (Tcl_SplitList(interp, string, &nColors, &colors) != TCL_OK) {
-           return TCL_ERROR;
-       }
-       switch (nColors) {
-       case 0:
-           result = TCL_OK;
-           break;
-       case 1:
-           result = GetColorPair(interp, tkwin, colors[0], "", &sample,
-               allowDefault);
-           break;
-       case 2:
-           result = GetColorPair(interp, tkwin, colors[0], colors[1],
-               &sample, allowDefault);
-           break;
-       default:
-           result = TCL_ERROR;
-           Tcl_AppendResult(interp, "too many names in colors list",
-               (char *)NULL);
-       }
-       Blt_Free(colors);
-       if (result != TCL_OK) {
-           return TCL_ERROR;
-       }
-    }
-    Blt_FreeColorPair(pairPtr);
-    *pairPtr = sample;
-    return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * NameOfColor --
- *
- *     Convert the color option value into a string.
- *
- * Results:
- *     The static string representing the color option is returned.
- *
- *----------------------------------------------------------------------
- */
-static char *
-NameOfColor(colorPtr)
-    XColor *colorPtr;
-{
-    if (colorPtr == NULL) {
-       return "";
-    } else if (colorPtr == COLOR_DEFAULT) {
-       return "defcolor";
-    } else {
-       return Tk_NameOfColor(colorPtr);
-    }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * ColorPairToString --
- *
- *     Convert the color pairs into color names.
- *
- * Results:
- *     The string representing the symbol color is returned.
- *
- *----------------------------------------------------------------------
- */
-/*ARGSUSED*/
-static char *
-ColorPairToString(clientData, tkwin, widgRec, offset, freeProcPtr)
-    ClientData clientData;     /* Not used. */
-    Tk_Window tkwin;           /* Not used. */
-    char *widgRec;             /* Element information record */
-    int offset;                        /* Offset of symbol type field in record */
-    Tcl_FreeProc **freeProcPtr;        /* Not used. */
-{
-    ColorPair *pairPtr = (ColorPair *)(widgRec + offset);
-    Tcl_DString dString;
-    char *result;
-
-    Tcl_DStringInit(&dString);
-    Tcl_DStringAppendElement(&dString, NameOfColor(pairPtr->fgColor));
-    Tcl_DStringAppendElement(&dString, NameOfColor(pairPtr->bgColor));
-    result = Tcl_DStringValue(&dString);
-    if (result == dString.staticSpace) {
-       result = Blt_Strdup(result);
-    }
-    *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
-    return result;
-}
-
-int
-Blt_PointInSegments(samplePtr, segments, nSegments, halo)
-    Point2D *samplePtr;
-    Segment2D *segments;
-    int nSegments;
-    double halo;
-{
-    register Segment2D *segPtr, *endPtr;
-    double left, right, top, bottom;
-    Point2D p, t;
-    double dist, minDist;
-
-    minDist = DBL_MAX;
-    for (segPtr = segments, endPtr = segments + nSegments; segPtr < endPtr; 
-        segPtr++) {
-       t = Blt_GetProjection((int)samplePtr->x, (int)samplePtr->y, 
-                     &segPtr->p, &segPtr->q);
-       if (segPtr->p.x > segPtr->q.x) {
-           right = segPtr->p.x, left = segPtr->q.x;
-       } else {
-           right = segPtr->q.x, left = segPtr->p.x;
-       }
-       if (segPtr->p.y > segPtr->q.y) {
-           bottom = segPtr->p.y, top = segPtr->q.y;
-       } else {
-           bottom = segPtr->q.y, top = segPtr->p.y;
-       }
-       p.x = BOUND(t.x, left, right);
-       p.y = BOUND(t.y, top, bottom);
-       dist = hypot(p.x - samplePtr->x, p.y - samplePtr->y);
-       if (dist < minDist) {
-           minDist = dist;
-       }
-    }
-    return (minDist < halo);
-}
-
-int
-Blt_PointInPolygon(samplePtr, points, nPoints)
-    Point2D *samplePtr;
-    Point2D *points;
-    int nPoints;
-{
-    double b;
-    register Point2D *p, *q, *endPtr;
-    register int count;
-
-    count = 0;
-    for (p = points, q = p + 1, endPtr = p + nPoints; q < endPtr; p++, q++) {
-       if (((p->y <= samplePtr->y) && (samplePtr->y < q->y)) || 
-           ((q->y <= samplePtr->y) && (samplePtr->y < p->y))) {
-           b = (q->x - p->x) * (samplePtr->y - p->y) / (q->y - p->y) + p->x;
-           if (samplePtr->x < b) {
-               count++;        /* Count the number of intersections. */
-           }
-       }
-    }
-    return (count & 0x01);
-}
-
-int
-Blt_RegionInPolygon(extsPtr, points, nPoints, enclosed)
-    Extents2D *extsPtr;
-    Point2D *points;
-    int nPoints;
-    int enclosed;
-{
-    register Point2D *pointPtr, *endPtr;
-
-    if (enclosed) {
-       /*  
-        * All points of the polygon must be inside the rectangle.
-        */
-       for (pointPtr = points, endPtr = points + nPoints; pointPtr < endPtr; 
-            pointPtr++) {
-           if ((pointPtr->x < extsPtr->left) ||
-               (pointPtr->x > extsPtr->right) ||
-               (pointPtr->y < extsPtr->top) ||
-               (pointPtr->y > extsPtr->bottom)) {
-               return FALSE;   /* One point is exterior. */
-           }
-       }
-       return TRUE;
-    } else {
-       Point2D p, q;
-
-       /*
-        * If any segment of the polygon clips the bounding region, the
-        * polygon overlaps the rectangle.
-        */
-       points[nPoints] = points[0];
-       for (pointPtr = points, endPtr = points + nPoints; pointPtr < endPtr; 
-            pointPtr++) {
-           p = *pointPtr;
-           q = *(pointPtr + 1);
-           if (Blt_LineRectClip(extsPtr, &p, &q)) {
-               return TRUE;
-           }
-       }
-       /* 
-        * Otherwise the polygon and rectangle are either disjoint
-        * or enclosed.  Check if one corner of the rectangle is
-        * inside the polygon.  
-        */
-       p.x = extsPtr->left;
-       p.y = extsPtr->top;
-       return Blt_PointInPolygon(&p, points, nPoints);
-    }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Blt_GraphExtents --
- *
- *     Generates a bounding box representing the plotting area of
- *     the graph. This data structure is used to clip the points and
- *     line segments of the line element.
- *
- *     The clip region is the plotting area plus such arbitrary extra
- *     space.  The reason we clip with a bounding box larger than the
- *     plot area is so that symbols will be drawn even if their center
- *     point isn't in the plotting area.
- *
- * Results:
- *     None.
- *
- * Side Effects:
- *     The bounding box is filled with the dimensions of the plotting
- *     area.
- *
- *----------------------------------------------------------------------
- */
-void
-Blt_GraphExtents(graphPtr, extsPtr)
-    Graph *graphPtr;
-    Extents2D *extsPtr;
-{
-    extsPtr->left = (double)(graphPtr->hOffset - graphPtr->padX.side1);
-    extsPtr->top = (double)(graphPtr->vOffset - graphPtr->padY.side1);
-    extsPtr->right = (double)(graphPtr->hOffset + graphPtr->hRange + 
-       graphPtr->padX.side2);
-    extsPtr->bottom = (double)(graphPtr->vOffset + graphPtr->vRange + 
-       graphPtr->padY.side2);
-}
-
-static int 
-ClipTest (double ds, double dr, double *t1, double *t2)
-{
-  double t;
-
-  if (ds < 0.0) {
-      t = dr / ds;
-      if (t > *t2) {
-         return FALSE;
-      } 
-      if (t > *t1) {
-         *t1 = t;
-      }
-  } else if (ds > 0.0) {
-      t = dr / ds;
-      if (t < *t1) {
-         return FALSE;
-      } 
-      if (t < *t2) {
-         *t2 = t;
-      }
-  } else {
-      /* d = 0, so line is parallel to this clipping edge */
-      if (dr < 0.0) { /* Line is outside clipping edge */
-         return FALSE;
-      }
-  }
-  return TRUE;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Blt_LineRectClip --
- *
- *     Clips the given line segment to a rectangular region.  The
- *     coordinates of the clipped line segment are returned.  The
- *     original coordinates are overwritten.
- *
- *     Reference:  Liang-Barsky Line Clipping Algorithm.
- *
- * Results:
- *     Returns if line segment is visible within the region. The
- *     coordinates of the original line segment are overwritten
- *     by the clipped coordinates.
- *
- *---------------------------------------------------------------------- 
- */
-int 
-Blt_LineRectClip(extsPtr, p, q)
-    Extents2D *extsPtr;                /* Rectangular region to clip. */
-    Point2D *p, *q;            /* (in/out) Coordinates of original
-                                * and clipped line segment. */
-{
-    double t1, t2;
-    double dx, dy;
-
-    t1 = 0.0;
-    t2 = 1.0;
-    dx = q->x - p->x;
-    if ((ClipTest (-dx, p->x - extsPtr->left, &t1, &t2)) &&
-       (ClipTest (dx, extsPtr->right - p->x, &t1, &t2))) {
-       dy = q->y - p->y;
-       if ((ClipTest (-dy, p->y - extsPtr->top, &t1, &t2)) && 
-           (ClipTest (dy, extsPtr->bottom - p->y, &t1, &t2))) {
-           if (t2 < 1.0) {
-               q->x = p->x + t2 * dx;
-               q->y = p->y + t2 * dy;
-           }
-           if (t1 > 0.0) {
-               p->x += t1 * dx;
-               p->y += t1 * dy;
-           }
-           return TRUE;
-       }
-    }
-    return FALSE;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Blt_PolyRectClip --
- *
- *     Clips the given polygon to a rectangular region.  The resulting
- *     polygon is returned. Note that the resulting polyon may be 
- *     complex, connected by zero width/height segments.  The drawing 
- *     routine (such as XFillPolygon) will not draw a connecting
- *     segment.
- *
- *     Reference:  Liang-Barsky Polygon Clipping Algorithm 
- *
- * Results:
- *     Returns the number of points in the clipped polygon. The
- *     points of the clipped polygon are stored in *outputPts*.
- *
- *---------------------------------------------------------------------- 
- */
-#define EPSILON  FLT_EPSILON
-#define AddVertex(vx, vy)          r->x=(vx), r->y=(vy), r++, count++ 
-#define LastVertex(vx, vy)         r->x=(vx), r->y=(vy), count++ 
-
-int 
-Blt_PolyRectClip(extsPtr, points, nPoints, clipPts)
-    Extents2D *extsPtr;
-    Point2D *points;
-    int nPoints;
-    Point2D *clipPts;
-{
-    Point2D *endPtr;
-    double dx, dy;
-    double tin1, tin2;
-    double tinx, tiny;
-    double xin, yin, xout, yout;
-    int count;
-    register Point2D *p;       /* First vertex of input polygon edge. */
-    register Point2D *q;       /* Last vertex of input polygon edge. */
-    register Point2D *r;
-
-    r = clipPts;
-    count = 0;                 /* Counts # of vertices in output polygon. */
-
-    points[nPoints] = points[0];
-
-    for (p = points, q = p + 1, endPtr = p + nPoints; p < endPtr; p++, q++) {
-       dx = q->x - p->x;       /* X-direction */
-       dy = q->y - p->y;       /* Y-direction */
-
-       if (FABS(dx) < EPSILON) { 
-           dx = (p->x > extsPtr->left) ? -EPSILON : EPSILON ;
-       }
-       if (FABS(dy) < EPSILON) { 
-           dy = (p->y > extsPtr->top) ? -EPSILON : EPSILON ;
-       }
-
-       if (dx > 0.0) {         /* Left */
-           xin = extsPtr->left;
-           xout = extsPtr->right + 1.0;
-       } else {                /* Right */
-           xin = extsPtr->right + 1.0;
-           xout = extsPtr->left;
-       }
-       if (dy > 0.0) {         /* Top */
-           yin = extsPtr->top;
-           yout = extsPtr->bottom + 1.0;
-       } else {                /* Bottom */
-           yin = extsPtr->bottom + 1.0;
-           yout = extsPtr->top;
-       }
-       
-       tinx = (xin - p->x) / dx;
-       tiny = (yin - p->y) / dy;
-       
-       if (tinx < tiny) {      /* Hits x first */
-           tin1 = tinx;
-           tin2 = tiny;
-       } else {                /* Hits y first */
-           tin1 = tiny;
-           tin2 = tinx;
-       }
-       
-       if (tin1 <= 1.0) {
-           if (tin1 > 0.0) {
-               AddVertex(xin, yin);
-            }
-           if (tin2 <= 1.0) {
-               double toutx, touty, tout1;
-
-               toutx = (xout - p->x) / dx;
-               touty = (yout - p->y) / dy;
-               tout1 = MIN(toutx, touty);
-               
-               if ((tin2 > 0.0) || (tout1 > 0.0)) {
-                   if (tin2 <= tout1) {
-                       if (tin2 > 0.0) {
-                           if (tinx > tiny) {
-                               AddVertex(xin, p->y + tinx * dy);
-                           } else {
-                               AddVertex(p->x + tiny * dx, yin);
-                           }
-                       }
-                       if (tout1 < 1.0) {
-                           if (toutx < touty) {
-                               AddVertex(xout, p->y + toutx * dy);
-                           } else {
-                               AddVertex(p->x + touty * dx, yout);
-                           }
-                       } else {
-                           AddVertex(q->x, q->y);
-                       }
-                   } else {
-                       if (tinx > tiny) {
-                           AddVertex(xin, yout);
-                       } else {
-                           AddVertex(xout, yin);
-                       }
-                   }
-               }
-            }
-       }
-    }
-    if (count > 0) {
-       LastVertex(clipPts[0].x, clipPts[0].y);
-    }
-    return count;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Blt_GetProjection --
- *
- *     Computes the projection of a point on a line.  The line (given
- *     by two points), is assumed the be infinite.
- *
- *     Compute the slope (angle) of the line and rotate it 90 degrees.
- *     Using the slope-intercept method (we know the second line from
- *     the sample test point and the computed slope), then find the
- *     intersection of both lines. This will be the projection of the
- *     sample point on the first line.
- *
- * Results:
- *     Returns the coordinates of the projection on the line.
- *
- *----------------------------------------------------------------------
- */
-Point2D
-Blt_GetProjection(x, y, p, q)
-    int x, y;                  /* Screen coordinates of the sample point. */
-    Point2D *p, *q;            /* Line segment to project point onto */
-{
-    double dx, dy;
-    Point2D t;
-
-    dx = p->x - q->x;
-    dy = p->y - q->y;
-
-    /* Test for horizontal and vertical lines */
-    if (FABS(dx) < DBL_EPSILON) {
-       t.x = p->x, t.y = (double)y;
-    } else if (FABS(dy) < DBL_EPSILON) {
-       t.x = (double)x, t.y = p->y;
-    } else {
-       double m1, m2;          /* Slope of both lines */
-       double b1, b2;          /* y-intercepts */
-       double midX, midY;      /* Midpoint of line segment. */
-       double ax, ay, bx, by;
-
-       /* Compute the slop and intercept of the line segment. */
-       m1 = (dy / dx);
-       b1 = p->y - (p->x * m1);
-
-       /* 
-        * Compute the slope and intercept of a second line segment:
-        * one that intersects through sample X-Y coordinate with a
-        * slope perpendicular to original line. 
-        */
-
-       /* Find midpoint of original segment. */
-       midX = (p->x + q->x) * 0.5;
-       midY = (p->y + q->y) * 0.5;
-
-       /* Rotate the line 90 degrees */
-       ax = midX - (0.5 * dy);
-       ay = midY - (0.5 * -dx);
-       bx = midX + (0.5 * dy);
-       by = midY + (0.5 * -dx);
-
-       m2 = (ay - by) / (ax - bx);
-       b2 = y - (x * m2);
-
-       /*
-        * Given the equations of two lines which contain the same point,
-        *
-        *    y = m1 * x + b1
-        *    y = m2 * x + b2
-        *
-        * solve for the intersection.
-        *
-        *    x = (b2 - b1) / (m1 - m2)
-        *    y = m1 * x + b1
-        *
-        */
-
-       t.x = (b2 - b1) / (m1 - m2);
-       t.y = m1 * t.x + b1;
-    }
-    return t;
-}
-
-typedef struct {
-    double hue, sat, val;
-} HSV;
-
-#define SetColor(c,r,g,b) ((c)->red = (int)((r) * 65535.0), \
-                          (c)->green = (int)((g) * 65535.0), \
-                          (c)->blue = (int)((b) * 65535.0))
-
-void
-Blt_XColorToHSV(colorPtr, hsvPtr)
-    XColor *colorPtr;
-    HSV *hsvPtr;
-{
-    unsigned short max, min;
-    double range;
-    unsigned short *colorValues;
-
-    /* Find the minimum and maximum RGB intensities */
-    colorValues = (unsigned short *)&colorPtr->red;
-    max = MAX3(colorValues[0], colorValues[1], colorValues[2]);
-    min = MIN3(colorValues[0], colorValues[1], colorValues[2]);
-
-    hsvPtr->val = (double)max / 65535.0;
-    hsvPtr->hue = hsvPtr->sat = 0.0;
-
-    range = (double)(max - min);
-    if (max != min) {
-       hsvPtr->sat = range / (double)max;
-    }
-    if (hsvPtr->sat > 0.0) {
-       double red, green, blue;
-
-       /* Normalize the RGB values */
-       red = (double)(max - colorPtr->red) / range;
-       green = (double)(max - colorPtr->green) / range;
-       blue = (double)(max - colorPtr->blue) / range;
-
-       if (colorPtr->red == max) {
-           hsvPtr->hue = (blue - green);
-       } else if (colorPtr->green == max) {
-           hsvPtr->hue = 2 + (red - blue);
-       } else if (colorPtr->blue == max) {
-           hsvPtr->hue = 4 + (green - red);
-       }
-       hsvPtr->hue *= 60.0;
-    } else {
-       hsvPtr->sat = 0.5;
-    }
-    if (hsvPtr->hue < 0.0) {
-       hsvPtr->hue += 360.0;
-    }
-}
-
-void
-Blt_HSVToXColor(hsvPtr, colorPtr)
-    HSV *hsvPtr;
-    XColor *colorPtr;
-{
-    double hue, p, q, t;
-    double frac;
-    int quadrant;
-
-    if (hsvPtr->val < 0.0) {
-       hsvPtr->val = 0.0;
-    } else if (hsvPtr->val > 1.0) {
-       hsvPtr->val = 1.0;
-    }
-    if (hsvPtr->sat == 0.0) {
-       SetColor(colorPtr, hsvPtr->val, hsvPtr->val, hsvPtr->val);
-       return;
-    }
-    hue = FMOD(hsvPtr->hue, 360.0) / 60.0;
-    quadrant = (int)floor(hue);
-    frac = hsvPtr->hue - quadrant;
-    p = hsvPtr->val * (1 - (hsvPtr->sat));
-    q = hsvPtr->val * (1 - (hsvPtr->sat * frac));
-    t = hsvPtr->val * (1 - (hsvPtr->sat * (1 - frac)));
-
-    switch (quadrant) {
-    case 0:
-       SetColor(colorPtr, hsvPtr->val, t, p);
-       break;
-    case 1:
-       SetColor(colorPtr, q, hsvPtr->val, p);
-       break;
-    case 2:
-       SetColor(colorPtr, p, hsvPtr->val, t);
-       break;
-    case 3:
-       SetColor(colorPtr, p, q, hsvPtr->val);
-       break;
-    case 4:
-       SetColor(colorPtr, t, p, hsvPtr->val);
-       break;
-    case 5:
-       SetColor(colorPtr, hsvPtr->val, p, q);
-       break;
-    }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Blt_AdjustViewport --
- *
- *     Adjusts the offsets of the viewport according to the scroll mode.
- *     This is to accommodate both "listbox" and "canvas" style scrolling.
- *
- *     "canvas"        The viewport scrolls within the range of world
- *                     coordinates.  This way the viewport always displays
- *                     a full page of the world.  If the world is smaller
- *                     than the viewport, then (bizarrely) the world and
- *                     viewport are inverted so that the world moves up
- *                     and down within the viewport.
- *
- *     "listbox"       The viewport can scroll beyond the range of world
- *                     coordinates.  Every entry can be displayed at the
- *                     top of the viewport.  This also means that the
- *                     scrollbar thumb weirdly shrinks as the last entry
- *                     is scrolled upward.
- *
- * Results:
- *     The corrected offset is returned.
- *
- *----------------------------------------------------------------------
- */
-int
-Blt_AdjustViewport(offset, worldSize, windowSize, scrollUnits, scrollMode)
-    int offset, worldSize, windowSize;
-    int scrollUnits;
-    int scrollMode;
-{
-    switch (scrollMode) {
-    case BLT_SCROLL_MODE_CANVAS:
-
-       /*
-        * Canvas-style scrolling allows the world to be scrolled
-        * within the window.
-        */
-
-       if (worldSize < windowSize) {
-           if ((worldSize - offset) > windowSize) {
-               offset = worldSize - windowSize;
-           }
-           if (offset > 0) {
-               offset = 0;
-           }
-       } else {
-           if ((offset + windowSize) > worldSize) {
-               offset = worldSize - windowSize;
-           }
-           if (offset < 0) {
-               offset = 0;
-           }
-       }
-       break;
-
-    case BLT_SCROLL_MODE_LISTBOX:
-       if (offset < 0) {
-           offset = 0;
-       }
-       if (offset >= worldSize) {
-           offset = worldSize - scrollUnits;
-       }
-       break;
-
-    case BLT_SCROLL_MODE_HIERBOX:
-
-       /*
-        * Hierbox-style scrolling allows the world to be scrolled
-        * within the window.
-        */
-       if ((offset + windowSize) > worldSize) {
-           offset = worldSize - windowSize;
-       }
-       if (offset < 0) {
-           offset = 0;
-       }
-       break;
-    }
-    return offset;
-}
-
-int
-Blt_GetScrollInfo(interp, argc, argv, offsetPtr, worldSize, windowSize,
-    scrollUnits, scrollMode)
-    Tcl_Interp *interp;
-    int argc;
-    char **argv;
-    int *offsetPtr;
-    int worldSize, windowSize;
-    int scrollUnits;
-    int scrollMode;
-{
-    char c;
-    unsigned int length;
-    int offset;
-    int count;
-    double fract;
-
-    offset = *offsetPtr;
-    c = argv[0][0];
-    length = strlen(argv[0]);
-    if ((c == 's') && (strncmp(argv[0], "scroll", length) == 0)) {
-       if (argc != 3) {
-           return TCL_ERROR;
-       }
-       /* scroll number unit/page */
-       if (Tcl_GetInt(interp, argv[1], &count) != TCL_OK) {
-           return TCL_ERROR;
-       }
-       c = argv[2][0];
-       length = strlen(argv[2]);
-       if ((c == 'u') && (strncmp(argv[2], "units", length) == 0)) {
-           fract = (double)count *scrollUnits;
-       } else if ((c == 'p') && (strncmp(argv[2], "pixels", length) == 0)) {
-           fract = (double)count;
-       } else if ((c == 'p') && (strncmp(argv[2], "pages", length) == 0)) {
-           /* A page is 90% of the view-able window. */
-           fract = (double)count *windowSize * 0.9;
-       } else {
-           Tcl_AppendResult(interp, "unknown \"scroll\" units \"", argv[2],
-               "\"", (char *)NULL);
-           return TCL_ERROR;
-       }
-       offset += (int)fract;
-    } else if ((c == 'm') && (strncmp(argv[0], "moveto", length) == 0)) {
-       if (argc != 2) {
-           return TCL_ERROR;
-       }
-       /* moveto fraction */
-       if (Tcl_GetDouble(interp, argv[1], &fract) != TCL_OK) {
-           return TCL_ERROR;
-       }
-       offset = (int)(worldSize * fract);
-    } else {
-       /* Treat like "scroll units" */
-       if (Tcl_GetInt(interp, argv[0], &count) != TCL_OK) {
-           return TCL_ERROR;
-       }
-       fract = (double)count *scrollUnits;
-       offset += (int)fract;
-    }
-    *offsetPtr = Blt_AdjustViewport(offset, worldSize, windowSize, scrollUnits,
-       scrollMode);
-    return TCL_OK;
-}
-
-#if (TCL_MAJOR_VERSION >= 8)
-int
-Blt_GetScrollInfoFromObj(interp, objc, objv, offsetPtr, worldSize, windowSize,
-    scrollUnits, scrollMode)
-    Tcl_Interp *interp;
-    int objc;
-    Tcl_Obj *CONST *objv;
-    int *offsetPtr;
-    int worldSize, windowSize;
-    int scrollUnits;
-    int scrollMode;
-{
-    char c;
-    unsigned int length;
-    int offset;
-    int count;
-    double fract;
-    char *string;
-
-    offset = *offsetPtr;
-
-    string = Tcl_GetString(objv[0]);
-    c = string[0];
-    length = strlen(string);
-    if ((c == 's') && (strncmp(string, "scroll", length) == 0)) {
-       if (objc != 3) {
-           return TCL_ERROR;
-       }
-       /* scroll number unit/page */
-       if (Tcl_GetIntFromObj(interp, objv[1], &count) != TCL_OK) {
-           return TCL_ERROR;
-       }
-       string = Tcl_GetString(objv[2]);
-       c = string[0];
-       length = strlen(string);
-       if ((c == 'u') && (strncmp(string, "units", length) == 0)) {
-           fract = (double)count *scrollUnits;
-       } else if ((c == 'p') && (strncmp(string, "pixels", length) == 0)) {
-             fract = (double)count;
-       } else if ((c == 'p') && (strncmp(string, "pages", length) == 0)) {
-           /* A page is 90% of the view-able window. */
-           fract = (double)count *windowSize * 0.9;
-       } else {
-           Tcl_AppendResult(interp, "unknown \"scroll\" units \"", 
-                    Tcl_GetString(objv[2]), "\"", (char *)NULL);
-           return TCL_ERROR;
-       }
-       offset += (int)fract;
-    } else if ((c == 'm') && (strncmp(string, "moveto", length) == 0)) {
-       if (objc != 2) {
-           return TCL_ERROR;
-       }
-       /* moveto fraction */
-       if (Tcl_GetDoubleFromObj(interp, objv[1], &fract) != TCL_OK) {
-           return TCL_ERROR;
-       }
-       offset = (int)(worldSize * fract);
-    } else {
-       /* Treat like "scroll units" */
-       if (Tcl_GetIntFromObj(interp, objv[0], &count) != TCL_OK) {
-           return TCL_ERROR;
-       }
-       fract = (double)count *scrollUnits;
-       offset += (int)fract;
-    }
-    *offsetPtr = Blt_AdjustViewport(offset, worldSize, windowSize, scrollUnits,
-       scrollMode);
-    return TCL_OK;
-}
-#endif /* TCL_MAJOR_VERSION >= 8 */
-
-/*
- * ----------------------------------------------------------------------
- *
- * Blt_UpdateScrollbar --
- *
- *     Invoke a Tcl command to the scrollbar, defining the new
- *     position and length of the scroll. See the Tk documentation
- *     for further information on the scrollbar.  It is assumed the
- *     scrollbar command prefix is valid.
- *
- * Results:
- *     None.
- *
- * Side Effects:
- *     Scrollbar is commanded to change position and/or size.
- *
- * ----------------------------------------------------------------------
- */
-void
-Blt_UpdateScrollbar(interp, scrollCmd, firstFract, lastFract)
-    Tcl_Interp *interp;
-    char *scrollCmd;           /* scrollbar command */
-    double firstFract, lastFract;
-{
-    char string[200];
-    Tcl_DString dString;
-
-    Tcl_DStringInit(&dString);
-    Tcl_DStringAppend(&dString, scrollCmd, -1);
-    if (firstFract<0.0) { firstFract = 0; }
-    if (lastFract>1.0) { lastFract = 1; }
-    sprintf(string, " %f %f", firstFract, lastFract);
-    Tcl_DStringAppend(&dString, string, -1);
-    if (Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)) != TCL_OK) {
-       Tcl_BackgroundError(interp);
-    }
-    Tcl_DStringFree(&dString);
-}
-
-/* -------------- */
-/*
- *----------------------------------------------------------------------
- *
- * Blt_GetPrivateGCFromDrawable --
- *
- *      Like Tk_GetGC, but doesn't share the GC with any other widget.
- *     This is needed because the certain GC parameters (like dashes)
- *     can not be set via XCreateGC, therefore there is no way for
- *     Tk's hashing mechanism to recognize that two such GCs differ.
- *
- * Results:
- *      A new GC is returned.
- *
- *----------------------------------------------------------------------
- */
-GC
-Blt_GetPrivateGCFromDrawable(display, drawable, gcMask, valuePtr)
-    Display *display;
-    Drawable drawable;
-    unsigned long gcMask;
-    XGCValues *valuePtr;
-{
-    GC newGC;
-
-#ifdef WIN32
-    newGC = Blt_EmulateXCreateGC(display, drawable, gcMask, valuePtr);
-#else
-    newGC = XCreateGC(display, drawable, gcMask, valuePtr);
-#endif
-    return newGC;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Blt_GetPrivateGC --
- *
- *      Like Tk_GetGC, but doesn't share the GC with any other widget.
- *     This is needed because the certain GC parameters (like dashes)
- *     can not be set via XCreateGC, therefore there is no way for
- *     Tk's hashing mechanism to recognize that two such GCs differ.
- *
- * Results:
- *      A new GC is returned.
- *
- *----------------------------------------------------------------------
- */
-GC
-Blt_GetPrivateGC(tkwin, gcMask, valuePtr)
-    Tk_Window tkwin;
-    unsigned long gcMask;
-    XGCValues *valuePtr;
-{
-    GC gc;
-    Pixmap pixmap;
-    Drawable drawable;
-    Display *display;
-
-    pixmap = None;
-    drawable = Tk_WindowId(tkwin);
-    display = Tk_Display(tkwin);
-
-    if (drawable == None) {
-       Drawable root;
-       int depth;
-
-       root = RootWindow(display, Tk_ScreenNumber(tkwin));
-       depth = Tk_Depth(tkwin);
-
-       if (depth == DefaultDepth(display, Tk_ScreenNumber(tkwin))) {
-           drawable = root;
-       } else {
-           pixmap = Tk_GetPixmap(display, root, 1, 1, depth);
-           drawable = pixmap;
-       }
-    }
-    gc = Blt_GetPrivateGCFromDrawable(display, drawable, gcMask, valuePtr);
-    if (pixmap != None) {
-       Tk_FreePixmap(display, pixmap);
-    }
-    return gc;
-}
-
-void
-Blt_FreePrivateGC(display, gc)
-    Display *display;
-    GC gc;
-{
-    Tk_FreeXId(display, (XID) XGContextFromGC(gc));
-    XFreeGC(display, gc);
-}
-
-#ifndef WIN32
-void
-Blt_SetDashes(display, gc, dashesPtr)
-    Display *display;
-    GC gc;
-    Blt_Dashes *dashesPtr;
-{
-    XSetDashes(display, gc, dashesPtr->offset, 
-       (CONST char *)dashesPtr->values, strlen((char *)dashesPtr->values));
-}
-#endif
-
-
-static double
-FindSplit(points, i, j, split) 
-    Point2D points[];
-    int i, j;                  /* Indices specifying the range of points. */
-    int *split;                        /* (out) Index of next split. */
-{    double maxDist;
-    
-    maxDist = -1.0;
-    if ((i + 1) < j) {
-       register int k;
-       double a, b, c; 
-       double sqDist;
-
-       /* 
-        * 
-        * sqDist P(k) =  |  1  P(i).x  P(i).y  |
-        *                |  1  P(j).x  P(j).y  |
-        *                |  1  P(k).x  P(k).y  |
-        *              ---------------------------
-        *       (P(i).x - P(j).x)^2 + (P(i).y - P(j).y)^2
-        */
-
-       a = points[i].y - points[j].y;
-       b = points[j].x - points[i].x;
-       c = (points[i].x * points[j].y) - (points[i].y * points[j].x);
-       for (k = (i + 1); k < j; k++) {
-           sqDist = (points[k].x * a) + (points[k].y * b) + c;
-           if (sqDist < 0.0) {
-               sqDist = -sqDist;       
-           }
-           if (sqDist > maxDist) {
-               maxDist = sqDist;       /* Track the maximum. */
-               *split = k;
-           }
-       }
-       /* Correction for segment length---should be redone if can == 0 */
-       maxDist *= maxDist / (a * a + b * b);
-    } 
-    return maxDist;
-}
-
-
-/* Douglas-Peucker line simplification algorithm */
-int
-Blt_SimplifyLine(inputPts, low, high, tolerance, indices) 
-   Point2D inputPts[];
-   int low, high;
-   double tolerance;
-   int indices[];
-{
-#define StackPush(a)   s++, stack[s] = (a)
-#define StackPop(a)    (a) = stack[s], s--
-#define StackEmpty()   (s < 0)
-#define StackTop()     stack[s]
-    int *stack;
-    int split = -1; 
-    double sqDist, sqTolerance;
-    int s = -1;                        /* Points to top stack item. */
-    int count;
-
-    stack = Blt_Malloc(sizeof(int) * (high - low + 1));
-    StackPush(high);
-    count = 0;
-    indices[count++] = 0;
-    sqTolerance = tolerance * tolerance;
-    while (!StackEmpty()) {
-       sqDist = FindSplit(inputPts, low, StackTop(), &split);
-       if (sqDist > sqTolerance) {
-           StackPush(split);
-       } else {
-           indices[count++] = StackTop();
-           StackPop(low);
-       }
-    } 
-    Blt_Free(stack);
-    return count;
-}
-
-void
-Blt_Draw2DSegments(display, drawable, gc, segPtr, nSegments)
-    Display *display;
-    Drawable drawable;
-    GC gc;
-    register Segment2D *segPtr;
-    int nSegments;
-{
-    XSegment *xSegPtr, *xSegArr;
-    Segment2D *endPtr;
-
-    xSegArr = Blt_Malloc(nSegments * sizeof(XSegment));
-    if (xSegArr == NULL) {
-       return;
-    }
-    xSegPtr = xSegArr;
-    for (endPtr = segPtr + nSegments; segPtr < endPtr; segPtr++) {
-       xSegPtr->x1 = (short int)segPtr->p.x;
-       xSegPtr->y1 = (short int)segPtr->p.y;
-       xSegPtr->x2 = (short int)segPtr->q.x;
-       xSegPtr->y2 = (short int)segPtr->q.y;
-       xSegPtr++;
-    }
-    XDrawSegments(display, drawable, gc, xSegArr, nSegments);
-    Blt_Free(xSegArr);
-}
-
-void
-Blt_DrawArrow(display, drawable, gc, x, y, arrowHeight, orientation)
-    Display *display;
-    Drawable drawable;
-    GC gc;
-    int x, y;
-    int arrowHeight;
-    int orientation;
-{
-    XPoint arrow[5];
-    int a, b;
-    
-    a = arrowHeight / 2 + 1;
-    b = arrowHeight;
-    switch (orientation) {
-    case ARROW_UP:
-       /*
-        *            0
-        *            +
-        *           / \
-        *          /   \
-        *         /     \  a
-        *        /       \
-        *   x,y /         \
-        *      +-----------+
-        *     1      b      2
-        */
-       arrow[0].x = x;
-       arrow[0].y = y - a;
-       arrow[1].x = arrow[0].x - b;
-       arrow[1].y = arrow[0].y + b;
-       arrow[2].x = arrow[0].x + b;
-       arrow[2].y = arrow[0].y + b;
-       arrow[3].x = arrow[0].x;
-       arrow[3].y = arrow[0].y;
-       break;
-
-    case ARROW_DOWN:
-       /*
-        *     1      b      2
-        *      +-----------+
-        *       \         /
-        *        \  x,y  /
-        *         \     /  a
-        *          \   /
-        *           \ /
-        *            +
-        *            0
-        */
-       arrow[0].x = x;
-       arrow[0].y = y + a;
-       arrow[1].x = arrow[0].x - b;
-       arrow[1].y = arrow[0].y - b;
-       arrow[2].x = arrow[0].x + b;
-       arrow[2].y = arrow[0].y - b;
-       arrow[3].x = arrow[0].x;
-       arrow[3].y = arrow[0].y;
-       break;
-
-    case ARROW_RIGHT:
-       /*
-        *       2
-        *       +
-        *       |\
-        *       | \
-        *       |  \ 
-        *       |   \
-        *       |    \
-        *       | x,y + 0
-        *       |    /
-        *       |   /
-        *       |  /
-        *       | /
-        *       |/
-        *       +
-        *       1
-        */
-       arrow[0].x = x + a;
-       arrow[0].y = y;
-       arrow[1].x = arrow[0].x - b;
-       arrow[1].y = arrow[0].y + b;
-       arrow[2].x = arrow[0].x - b;
-       arrow[2].y = arrow[0].y - b;
-       arrow[3].x = arrow[0].x;
-       arrow[3].y = arrow[0].y;
-       break;
-
-    case ARROW_LEFT:
-       /*
-        *              2
-        *              +
-        *             /|
-        *            / |
-        *           /  |
-        *          /   |
-        *         /    |
-        *       0+ x,y |
-        *         \    |
-        *          \   |
-        *           \  |
-        *            \ |
-        *             \|
-        *              +
-        *              1
-        */
-       arrow[0].x = x - a;
-       arrow[0].y = y;
-       arrow[1].x = arrow[0].x + b;
-       arrow[1].y = arrow[0].y + b;
-       arrow[2].x = arrow[0].x + b;
-       arrow[2].y = arrow[0].y - b;
-       arrow[3].x = arrow[0].x;
-       arrow[3].y = arrow[0].y;
-       break;
-
-    }
-    XFillPolygon(display, drawable, gc, arrow, 4, Convex, CoordModeOrigin);
-    XDrawLines(display, drawable, gc, arrow, 4, CoordModeOrigin);
-}
-
-int 
-Blt_MaxRequestSize(Display *display, unsigned int elemSize) 
-{
-    long size;
-
-#ifdef HAVE_XEXTENDEDMAXREQUESTSIZE
-    size = XExtendedMaxRequestSize(display);
-    if (size == 0) {
-       size = XMaxRequestSize(display);
-    }
-#else
-    size = XMaxRequestSize(display);
-#endif
-    size -= 4;
-    return ((size * 4) / elemSize);
-}
-
-#undef Blt_Fill3DRectangle
-void
-Blt_Fill3DRectangle(tkwin, drawable, border, x, y, width,
-       height, borderWidth, relief)
-    Tk_Window tkwin;           /* Window for which border was allocated. */
-    Drawable drawable;         /* X window or pixmap in which to draw. */
-    Tk_3DBorder border;                /* Token for border to draw. */
-    int x, y, width, height;   /* Outside area of rectangular region. */
-    int borderWidth;           /* Desired width for border, in
-                                * pixels. Border will be *inside* region. */
-    int relief;                        /* Indicates 3D effect: TK_RELIEF_FLAT,
-                                * TK_RELIEF_RAISED, or TK_RELIEF_SUNKEN. */
-{
-#ifndef notdef
-    if ((borderWidth > 1) && (width > 2) && (height > 2) &&
-       ((relief == TK_RELIEF_SUNKEN) || (relief == TK_RELIEF_RAISED))) {
-       GC lightGC, darkGC;
-       int x2, y2;
-
-       x2 = x + width - 1;
-       y2 = y + height - 1;
-#define TK_3D_LIGHT2_GC TK_3D_DARK_GC+1
-#define TK_3D_DARK2_GC TK_3D_DARK_GC+2
-       if (relief == TK_RELIEF_RAISED) {
-           lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
-#ifdef WIN32
-           darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
-#else
-           darkGC = DefaultGC(Tk_Display(tkwin), Tk_ScreenNumber(tkwin));
-#endif
-       } else {
-#ifdef WIN32
-           lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
-#else
-           lightGC = DefaultGC(Tk_Display(tkwin), Tk_ScreenNumber(tkwin));
-#endif
-           darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
-       }
-       XDrawLine(Tk_Display(tkwin), drawable, lightGC, x, y, x2, y);
-       XDrawLine(Tk_Display(tkwin), drawable, darkGC, x2, y2, x2, y);
-       XDrawLine(Tk_Display(tkwin), drawable, darkGC, x2, y2, x, y2);
-       XDrawLine(Tk_Display(tkwin), drawable, lightGC, x, y, x, y2);
-       x++, y++, width -= 2, height -= 2, borderWidth--;
-    }
-#endif
-    Tk_Fill3DRectangle(tkwin, drawable, border, x, y, width, height, 
-       borderWidth, relief);
-}
-
-
-#undef Blt_Draw3DRectangle
-void
-Blt_Draw3DRectangle(tkwin, drawable, border, x, y, width,
-       height, borderWidth, relief)
-    Tk_Window tkwin;           /* Window for which border was allocated. */
-    Drawable drawable;         /* X window or pixmap in which to draw. */
-    Tk_3DBorder border;                /* Token for border to draw. */
-    int x, y, width, height;   /* Outside area of rectangular region. */
-    int borderWidth;           /* Desired width for border, in
-                                * pixels. Border will be *inside* region. */
-    int relief;                        /* Indicates 3D effect: TK_RELIEF_FLAT,
-                                * TK_RELIEF_RAISED, or TK_RELIEF_SUNKEN. */
-{
-#ifndef notdef
-    if ((borderWidth > 1) && (width > 2) && (height > 2) &&
-       ((relief == TK_RELIEF_SUNKEN) || (relief == TK_RELIEF_RAISED))) {
-       GC lightGC, darkGC;
-       int x2, y2;
-
-       x2 = x + width - 1;
-       y2 = y + height - 1;
-       if (relief == TK_RELIEF_RAISED) {
-           lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
-#ifdef WIN32
-           darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
-#else
-           darkGC = DefaultGC(Tk_Display(tkwin), Tk_ScreenNumber(tkwin));
-#endif
-       } else {
-#ifdef WIN32
-           lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
-#else
-           lightGC = DefaultGC(Tk_Display(tkwin), Tk_ScreenNumber(tkwin));
-#endif
-           darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
-       }
-       XDrawLine(Tk_Display(tkwin), drawable, darkGC, x2, y2, x2, y);
-       XDrawLine(Tk_Display(tkwin), drawable, lightGC, x, y, x2, y);
-       XDrawLine(Tk_Display(tkwin), drawable, darkGC, x2, y2, x, y2);
-       XDrawLine(Tk_Display(tkwin), drawable, lightGC, x, y, x, y2);
-       x++, y++, width -= 2, height -= 2, borderWidth--;
-    }
-#endif
-    Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width, height, 
-       borderWidth, relief);
-}
-
-#ifdef notdef
-typedef struct {
-    Screen *screen;
-    Visual *visual;
-    Colormap colormap;
-    Tk_Uid nameUid;
-} BorderKey;
-
-typedef struct {
-    Screen *screen;            /* Screen on which the border will be used. */
-    Visual *visual;            /* Visual for all windows and pixmaps using
-                                * the border. */
-    int depth;                 /* Number of bits per pixel of drawables where
-                                * the border will be used. */
-    Colormap colormap;         /* Colormap out of which pixels are
-                                * allocated. */
-    int refCount;              /* Number of active uses of this color
-                                * (each active use corresponds to a
-                                * call to Blt_Get3DBorder).  If this
-                                * count is 0, then this structure is
-                                * no longer valid and it isn't
-                                * present in borderTable: it is being
-                                * kept around only because there are
-                                * objects referring to it.  The
-                                * structure is freed when refCount is
-                                * 0. */
-
-    XColor *bgColorPtr;                /* Color of face. */
-    XColor *shadows[4];
-
-    Pixmap darkStipple;                /* Stipple pattern to use for drawing
-                                * shadows areas.  Used for displays with
-                                * <= 64 colors or where colormap has filled
-                                * up. */
-    Pixmap lightStipple;       /* Stipple pattern to use for drawing
-                                * shadows areas.  Used for displays with
-                                * <= 64 colors or where colormap has filled
-                                * up. */
-    GC bgGC;                   /* Used (if necessary) to draw areas in
-                                * the background color. */
-    GC lightGC, darkGC;
-    Tcl_HashEntry *hashPtr;    /* Entry in borderTable (needed in
-                                * order to delete structure). */
-
-    struct Blt_3DBorderStruct *nextPtr;
-} Border, *Blt_3DBorder;
-    
-
-void
-Blt_Draw3DRectangle(tkwin, drawable, border, x, y, width,
-       height, borderWidth, relief)
-    Tk_Window tkwin;           /* Window for which border was allocated. */
-    Drawable drawable;         /* X window or pixmap in which to draw. */
-    Blt_3DBorder *borderPtr;   /* Border to draw. */
-    int x, y, width, height;   /* Outside area of rectangular region. */
-    int borderWidth;           /* Desired width for border, in
-                                * pixels. Border will be *inside* region. */
-    int relief;                        /* Indicates 3D effect: TK_RELIEF_FLAT,
-                                * TK_RELIEF_RAISED, or TK_RELIEF_SUNKEN. */
-{
-    if ((width > (2 * borderWidth)) && (height > (2 * borderWidth))) {
-       int x2, y2;
-       int i;
-
-       x2 = x + width - 1;
-       y2 = y + height - 1;
-
-       XSetForeground(borderPtr->lightGC, borderPtr->shadows[0]);
-       XSetForeground(borderPtr->darkGC, borderPtr->shadows[3]);
-       XDrawLine(Tk_Display(tkwin), drawable, borderPtr->lightGC, 
-                 x, y, x2, y);
-       XDrawLine(Tk_Display(tkwin), drawable, borderPtr->lightGC, 
-                 x, y, x, y2);
-       XDrawLine(Tk_Display(tkwin), drawable, borderPtr->darkGC, 
-                 x2, y, x2, y2);
-       XDrawLine(Tk_Display(tkwin), drawable, borderPtr->darkGC, 
-                 x2, y2, x, y2);
-       XSetForeground(borderPtr->lightGC, borderPtr->shadows[1]);
-       XSetForeground(borderPtr->darkGC, borderPtr->shadows[2]);
-       for (i = 1; i < (borderWidth - 1); i++) {
-
-           /*
-            *  +---------
-            *  |+-------
-            *  ||+-----
-            *  |||
-            *  |||
-            *  ||
-            *  |
-            */
-           x++, y++, x2--, y2--;
-           XDrawLine(Tk_Display(tkwin), drawable, borderPtr->lightGC, 
-               x, y, x2, y);
-           XDrawLine(Tk_Display(tkwin), drawable, borderPtr->lightGC, 
-               x, y, x, y2);
-           XDrawLine(Tk_Display(tkwin), drawable, borderPtr->darkGC, 
-               x2, y, x2, y2);
-           XDrawLine(Tk_Display(tkwin), drawable, borderPtr->darkGC, 
-               x2, y2, x, y2);
-       }
-    }
-}
-
-void
-Blt_Fill3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, 
-       relief)
-    Tk_Window tkwin;           /* Window for which border was allocated. */
-    Drawable drawable;         /* X window or pixmap in which to draw. */
-    Tk_3DBorder border;                /* Token for border to draw. */
-    int x, y, width, height;   /* Outside area of rectangular region. */
-    int borderWidth;           /* Desired width for border, in
-                                * pixels. Border will be *inside* region. */
-    int relief;                        /* Indicates 3D effect: TK_RELIEF_FLAT,
-                                * TK_RELIEF_RAISED, or TK_RELIEF_SUNKEN. */
-{
-    Blt_3DBorder *borderPtr;
-
-    XFillRectangle(Tk_Display(tkwin), drawable, borderPtr->bgGC, x, y, width,
-          height);
-    if ((borderWidth > 0) && (relief != BLT_RELIEF_FLAT)) {
-       Blt_Draw3DRectangle(tkwin, drawable, borderPtr, x, y, width, height, 
-           borderWidth, relief);
-    }
-}
-
-
-void 
-FreeBorder(display, borderPtr)
-    Display *display;
-    Border *borderPtr;
-{
-    int i;
-
-    if (borderPtr->bgColorPtr != NULL) {
-       Tk_FreeColor(display, borderPtr->bgColorPtr);
-    }
-    for (i = 0; i < 4; i++) {
-       Tk_FreeColor(display, borderPtr->shadows[i]);
-    }
-    if (borderPtr->tile != NULL) {
-       Blt_FreeTile(tile);
-    }
-    if (borderPtr->darkGC != NULL) {
-       Blt_FreePrivateGC(display, borderPtr->darkGC);
-    }
-    if (borderPtr->lightGC != NULL) {
-       Blt_FreePrivateGC(tkwin, borderPtr->lightGC);
-    }
-    if (borderPtr->bgGC != NULL) {
-       Blt_FreePrivateGC(tkwin, borderPtr->bgGC);
-    }
-    Blt_Free(borderPtr);
-}
-
-void
-Blt_Free3DBorder(display, border)
-    Display *display;
-    Blt_3DBorder border;
-{
-    Border *borderPtr = (Border *)border;
-
-    borderPtr->refCount--;
-    if (borderPtr->refCount >= 0) {
-       /* Search for the border in the bucket. Start at the head. */
-       headPtr = Blt_GetHashValue(borderPtr->hashPtr);
-       lastPtr = NULL;
-       while ((headPtr != borderPtr) && (headPtr != NULL)) {
-           lastPtr = headPtr;
-           headPtr = headPtr->next;
-       }
-       if (headPtr == NULL) {
-           return;             /* This can't happen. It means that 
-                                * we could not find the border. */
-       }
-       if (lastPtr != NULL) {
-           lastPtr->next = borderPtr->next;
-       } else {
-           Tcl_DeleteHashEntry(borderPtr->hashPtr);
-       }
-       FreeBorder(display, borderPtr);
-    }
-}
-
-Blt_3DBorder *
-Blt_Get3DBorder(interp, tkwin, borderName)
-    Tcl_Interp *interp;
-    Tk_Window tkwin;
-    char *borderName;
-{
-    Blt_3DBorder *borderPtr, *lastBorderPtr;
-    Blt_HashEntry *hPtr;
-    Blt_Tile tile;
-    XColor *bgColorPtr;
-    char **argv;
-    char *colorName;
-    int argc;
-    int isNew;
-
-    lastBorderPtr = NULL;
-    hPtr = Tcl_CreateHashEntry(&dataPtr->borderTable, borderName, &isNew);
-    if (!isNew) {
-       borderPtr = lastBorderPtr = Blt_GetHashValue(hPtr);
-       while (borderPtr != NULL) {
-           if ((Tk_Screen(tkwin) == borderPtr->screen) && 
-               (Tk_Colormap(tkwin) == borderPtr->colormap)) {
-               borderPtr->refCount++;
-               return borderPtr;
-           }
-           borderPtr = borderPtr->nextPtr;
-       }
-    }
-    /* Create a new border. */
-    argv = NULL;
-    bgColorPtr = NULL;
-    tile = NULL;
-
-    if (Tcl_SplitList(interp, borderName, &argc, &argv) != TCL_OK) {
-       goto error;
-    }
-    colorName = borderName;
-    if ((argc == 2) && (Blt_GetTile(interp, tkwin, argv[0], &tile) == TCL_OK)) {
-       colorName = argv[1];
-    }
-    bgColorPtr = Tk_GetColor(interp, tkwin, colorName);
-    if (bgColorPtr == NULL) {
-       goto error;
-    }
-
-    /* Create a new border */
-    borderPtr = Blt_Calloc(1, sizeof(Blt_3DBorder));
-    assert(borderPtr);
-    borderPtr->screen = Tk_Screen(tkwin);
-    borderPtr->visual = Tk_Visual(tkwin);
-    borderPtr->depth = Tk_Depth(tkwin);
-    borderPtr->colormap = Tk_Colormap(tkwin);
-    borderPtr->refCount = 1;
-    borderPtr->bgColorPtr = bgColorPtr;
-    borderPtr->tile = tile;
-    borderPtr->darkGC = Blt_GetPrivateGC(tkwin, 0, NULL);
-    borderPtr->lightGC = Blt_GetPrivateGC(tkwin, 0, NULL);
-    borderPtr->hashPtr = lastBorderPtr->hashPtr;
-    lastBorderPtr->nextPtr = lastBorderPtr;
-    {
-       HSV hsv;
-       XColor color;
-       double sat, sat0, diff, step, hstep;
-       int count;
-       
-       /* Convert the face (background) color to HSV */
-       Blt_XColorToHSV(borderPtr->bgColorPtr, &hsv);
-       
-       /* Using the color as the baseline intensity, pick a set of
-        * colors around the intensity. */
-#define UFLOOR(x,u)            (floor((x)*(u))/(u))
-       diff = hsv.sat - UFLOOR(hsv.sat, 0.2);
-       sat = 0.1 + (diff - 0.1);
-       sat0 = hsv.sat;
-       count = 0;
-       for (sat = 0.1 + (diff - 0.1); sat <= 1.0; sat += 0.2) {
-           if (FABS(sat0 - sat) >= 0.1) {
-               hsv.sat = sat;
-               Blt_HSVToXColor(&hsv, &color);
-               borderPtr->shadows[count] = Tk_GetColorByValue(tkwin, &color);
-               count++;
-           }
-       }
-    }
-    Blt_SetHashValue(hPtr, borderPtr);
-    if (argv != NULL) {
-       Blt_Free(argv);
-    }
-    return TCL_OK;
-
- error:
-    if (argv != NULL) {
-       Blt_Free(argv);
-    }
-    if (tile != NULL) {
-       Blt_FreeTile(tile);
-    }
-    if (bgColorPtr != NULL) {
-       Tk_FreeColor(bgColorPtr);
-    }
-    if (isNew) {
-       Blt_DeleteHashEntry(&borderTable, hPtr);
-    }
-    return NULL;
-}
-
-#endif