Logo Search packages:      
Sourcecode: acm version File versions  Download package

gutil1.c

/*
 *  Copyright (c) 1994, Riley Rainey,  riley@netcon.com
 *
 *  Permission to use, copy, modify and distribute (without charge) this
 *  software, documentation, images, etc. is granted, provided that this 
 *  comment and the author's name is retained.
 *
 *  This software is provided by the author as is, and without any expressed
 *  or implied warranties, including, but not limited to, the implied
 *  warranties of merchantability and fitness for a particular purpose.  In no
 *  event shall the author be liable for any direct, indirect, incidental, or
 *  consequential damages arising in any way out of the use of this software.
 */

#include <Xm/Xm.h>
#include "gedit.h"

void WorldToWidget(), DrawGrid(), DrawRuler(), DrawWidget(), StringSize();
extern void PointToXYZ();

#define MINIMUM_GRID_SPACING  50
#define MINIMUM_RULER_SPACING 50
#define RULER_MARGIN          2
#define RULER_MAJOR_LENGTH    7
#define RULER_MINOR1_LENGTH   4
#define RULER_MINOR2_LENGTH   2
#define RULER_THICKNESS       2

void
RescaleView (w, factor)
Widget      w;
double      factor;
{
      polygon_t   *poly;
      point_t           *q;
      view_info_t *p;
      register int      i, j, xc, yc, zc;

      XtVaGetValues (w,
            XmNuserData,      &p,
            NULL);

      switch (p->layout) {

      case VL_NXNY:
      case VL_NYX:
            xc = (p->width + 1) / 2;
            yc = (p->height + 1) / 2;
            zc = (p->other_view->height + 1) / 2;
            p->other_view->origin_x =
                  p->origin_x = (p->origin_x - xc) * factor + xc;
            p->origin_y = (p->origin_y - yc) * factor + yc;
            p->other_view->origin_y =
                  (p->other_view->origin_y - zc) * factor + zc;
            break;

      case VL_NXZ:
            xc = (p->width + 1) / 2;
            yc = (p->other_view->height + 1) / 2;
            zc = (p->height + 1) / 2;
            p->other_view->origin_x =
                  p->origin_x = (p->origin_x - xc) * factor + xc;
            p->origin_y = (p->origin_y - zc) * factor + zc;
            p->other_view->origin_y =
                  (p->other_view->origin_y - yc) * factor + yc;
            break;

      case VL_NYZ:
            xc = (p->other_view->height + 1) / 2;
            yc = (p->width + 1) / 2;
            zc = (p->height + 1) / 2;
            p->other_view->origin_x =
                  p->origin_x = (p->origin_x - yc) * factor + yc;
            p->origin_y = (p->origin_y - zc) * factor + zc;
            p->other_view->origin_y =
                  (p->other_view->origin_y - xc) * factor + xc;
            break;

      }

      pixel_scale /= factor;

      for (i=0, poly=polygon_list; i < polygon_max; ++i, ++poly) {
            for (j=0, q=poly->point; j < poly->num_points; ++j, ++q) {
                  PointToXYZ (p, q);
            }
      }

      DrawWidget (w, False);
      DrawWidget (p->other_widget, False);
}

void
DrawWidget (w, immediate)
Widget      w;
Boolean     immediate;
{
      polygon_t   *poly;
      point_t           *q;
      view_info_t *p;
      register int      i, j;
      int         x1, y1, x2, y2;
      Display           *dpy;
      Drawable    d;
      Pixel       fg, bg;

      XtVaGetValues (w,
            XmNuserData,      &p,
            XmNforeground,    &fg,
            XmNbackground,    &bg,
            NULL);

      dpy = XtDisplay (w);
      d = XtWindow (w);

      if (d == 0)
            immediate = False;

      XSetForeground (dpy, p->gc, bg);
      if (immediate)
            XFillRectangle (dpy, d, p->gc, 0, 0, p->width, p->height);
      XFillRectangle (dpy, p->pixmap, p->gc, 0, 0, p->width, p->height);

      XSetForeground (dpy, p->gc, fg);
      XSetLineAttributes (dpy, p->gc, app_data.line_thickness, LineSolid,
            CapButt, JoinMiter);

      for (i=unsel_polygon; i >= 0; i = polygon_list[i].next) {
            poly = &polygon_list[i];
            if (poly->num_points == 0)
                  continue;
            WorldToWidget (p, &poly->point[poly->num_points-1], &x1, &y1);
            for (j=0, q=poly->point; j < poly->num_points; ++j, ++q) {
                  WorldToWidget (p, q, &x2, &y2);
                  if (immediate)
                        XDrawLine (dpy, d, p->gc, x1, y1, x2, y2);
                  XDrawLine (dpy, p->pixmap, p->gc, x1, y1, x2, y2);
                  x1 = x2;
                  y1 = y2;
            }
      }

      XSetForeground (dpy, p->gc, app_data.select_pixel);
      XSetLineAttributes (dpy, p->gc, app_data.selection_thickness, LineSolid,
            CapButt, JoinMiter);

      for (i=sel_polygon; i >= 0; i = polygon_list[i].next) {
            poly = &polygon_list[i];
            if (poly->num_points == 0)
                  continue;
            WorldToWidget (p, &poly->point[poly->num_points-1], &x1, &y1);
            for (j=0, q=poly->point; j < poly->num_points; ++j, ++q) {
                  WorldToWidget (p, q, &x2, &y2);
                  if (immediate)
                        XDrawLine (dpy, d, p->gc, x1, y1, x2, y2);
                  XDrawLine (dpy, p->pixmap, p->gc, x1, y1, x2, y2);
                  x1 = x2;
                  y1 = y2;
            }
      }

      if (immediate)
            DrawGrid (p, dpy, d);
      DrawGrid (p, dpy, p->pixmap);

      if (immediate)
            DrawRuler (p, dpy, d, bg);
      DrawRuler (p, dpy, p->pixmap, bg);

      if (immediate == False && d != 0)
            XCopyArea (dpy, p->pixmap, d, p->gc, 0, 0, p->width, p->height,
                  0, 0);
}

void
DrawPolygon (w, poly, immediate)
Widget      w;
polygon_t   *poly;
Boolean     immediate;
{

      point_t           *q;
      view_info_t *p;
      register int      j;
      int         x1, y1, x2, y2;
      Display           *dpy;
      Drawable    d;
      Pixel       fg, bg;

      XtVaGetValues (w,
            XmNuserData,      &p,
            XmNforeground,    &fg,
            XmNbackground,    &bg,
            NULL);

      dpy = XtDisplay (w);
      d = XtWindow (w);

      if (d == 0)
            immediate = False;

      XSetForeground (dpy, p->gc, fg);
      XSetLineAttributes (dpy, p->gc, app_data.line_thickness, LineSolid,
            CapButt, JoinMiter);

      if (poly->num_points == 0)
            return;

      WorldToWidget (p, &poly->point[poly->num_points-1], &x1, &y1);
      for (j=0, q=poly->point; j < poly->num_points; ++j, ++q) {
            WorldToWidget (p, q, &x2, &y2);
            if (immediate)
                  XDrawLine (dpy, d, p->gc, x1, y1, x2, y2);
            XDrawLine (dpy, p->pixmap, p->gc, x1, y1, x2, y2);
            x1 = x2;
            y1 = y2;
      }

      if (immediate == False && d != 0)
            XCopyArea (dpy, p->pixmap, d, p->gc, 0, 0, p->width, p->height,
                  0, 0);
}

void
WorldToWidget (p, q, x, y)
view_info_t *p;
point_t           *q;
int         *x, *y;
{
      switch (p->layout) {

      case VL_NXZ:
            *x = q->x;
            *y = q->z;
            break;

      case VL_NXNY:
            *x = q->x;
            *y = q->y;
            break;

      case VL_NYX:
            *x = q->y;
            *y = q->x;
            break;

      case VL_NYZ:
            *x = q->y;
            *y = q->z;
            break;
      }
}

void
DrawGrid (p, dpy, d)
view_info_t *p;
Display           *dpy;
Drawable    d;
{
      int   exp, n, x, y;

      if (app_data.show_grid == False)
            return;

      XSetForeground (dpy, p->grid_gc, app_data.grid_pixel);

      for (exp = 1; ; exp *= 10) {
            if (exp / pixel_scale >= MINIMUM_GRID_SPACING)
                  break;
            if (5.0 * exp / pixel_scale >= MINIMUM_GRID_SPACING) {
                  exp = 5 * exp;
                  break;
            }
      }

/*
 *  Y-axis lines
 */

      for (x=p->origin_x, n = 0; x > 0; ) {
            XDrawLine (dpy, d, p->grid_gc, x, 0, x, p->height);
            ++ n;
            x = p->origin_x - (int) (n * exp / pixel_scale);
      }

      for (x=p->origin_x, n = 0; x < p->width; ) {
            ++ n;
            x = p->origin_x + (int) (n * exp / pixel_scale);
            XDrawLine (dpy, d, p->grid_gc, x, 0, x, p->height);
      }

/*
 *  X-axis lines
 */

      for (y=p->origin_y, n = 0; y > 0; ) {
            XDrawLine (dpy, d, p->grid_gc, 0, y, p->width, y);
            ++ n;
            y = p->origin_y - (int) (n * exp / pixel_scale);
      }

      for (y=p->origin_y, n = 0; y < p->height; ) {
            ++ n;
            y = p->origin_y + (int) (n * exp / pixel_scale);
            XDrawLine (dpy, d, p->grid_gc, 0, y, p->width, y);
      }
}

void DrawSelectedPolygon (w, poly, immediate, erase)
Widget            w;
polygon_t   *poly;
Boolean           immediate, erase;
{
      register int      i;
      int         x1, x2, y1, y2;
      point_t           *q;
      view_info_t *p;
      Pixel       bg;
      Display           *dpy;
      Drawable    d;

      dpy = XtDisplay (w);
      d = XtWindow (w);

      if (d == 0)
            immediate = False;

      XtVaGetValues (w,
            XmNuserData,      &p,
            XmNbackground,    &bg,
            NULL);

      if (erase)
            XSetForeground (dpy, p->gc, bg);
      else
            XSetForeground (dpy, p->gc, app_data.select_pixel);

      XSetLineAttributes (dpy, p->gc, app_data.selection_thickness, LineSolid,
            CapButt, JoinMiter);

      WorldToWidget (p, &poly->point[poly->num_points-1], &x1, &y1);
      for (i=0, q=poly->point; i < poly->num_points; ++i, ++q) {
            WorldToWidget (p, q, &x2, &y2);
            if (immediate)
                  XDrawLine (dpy, d, p->gc, x1, y1, x2, y2);
            XDrawLine (dpy, p->pixmap, p->gc, x1, y1, x2, y2);
            x1 = x2;
            y1 = y2;
      }
}

void
DrawRuler (p, dpy, d, bg)
view_info_t *p;
Display           *dpy;
Drawable    d;
Pixel       bg;
{

      int         ruler_y, font_y, nseg, exp, n, x, xw, yw, xv;
      XSegment    seg[256];
      char        s[32];

/*
 *  we'll only display the horizontal ruler in the top window
 */

      if (p->other_widget == twindow)
            return;

      if (app_data.show_ruler == False)
            return;

      for (exp = 1; ; exp *= 10) {
            if (exp / pixel_scale >= MINIMUM_RULER_SPACING)
                  break;
            if (2.0 * exp / pixel_scale >= MINIMUM_RULER_SPACING) {
                  exp = 2 * exp;
                  break;
            }
            if (5.0 * exp / pixel_scale >= MINIMUM_RULER_SPACING) {
                  exp = 5 * exp;
                  break;
            }
      }

      ruler_y = p->height - (RULER_THICKNESS + 2 * RULER_MARGIN +
            RULER_MAJOR_LENGTH + app_data.ruler_font->max_bounds.ascent);

      font_y = ruler_y + RULER_THICKNESS + RULER_MARGIN +
            app_data.ruler_font->max_bounds.ascent - 2;

      XSetForeground (dpy, p->gc, bg);
      XFillRectangle (dpy, d, p->gc,
            0, ruler_y, p->width, p->height - ruler_y);

      XSetForeground (dpy, p->gc, app_data.grid_pixel);

      seg[0].x1 = 0;
      seg[0].x2 = p->width - 1;
      seg[0].y1 = seg[0].y2 = ruler_y;
      nseg = 1;

/*
 *  Major tick marks
 */

      for (x=p->origin_x, n = 0; x > 0; ) {
            seg[nseg].x1 = seg[nseg].x2 = x;
            seg[nseg].y1 = p->height - 1;
            seg[nseg].y2 = p->height - RULER_MAJOR_LENGTH;
            ++ nseg;
            xv = (int) (n * exp);
            sprintf (s, "%d", xv);
            StringSize (s, &xw, &yw);
            XDrawString (dpy, d, p->gc, x - xw / 2, font_y, s, strlen(s));
            ++ n;
            x = p->origin_x - (int) (n * exp / pixel_scale);
      }

      for (x=p->origin_x, n = 0; x < p->width; ) {
            ++ n;
            x = p->origin_x + (int) (n * exp / pixel_scale);
            xv = (int) (n * exp);
            sprintf (s, "%d", xv);
            StringSize (s, &xw, &yw);
            XDrawString (dpy, d, p->gc, x - xw / 2, font_y, s, strlen(s));
            seg[nseg].x1 = seg[nseg].x2 = x;
            seg[nseg].y1 = p->height - 1;
            seg[nseg].y2 = p->height - RULER_MAJOR_LENGTH;
            ++ nseg;
      }

      XSetLineAttributes (dpy, p->gc, RULER_THICKNESS, LineSolid,
            CapButt, JoinMiter);

      XDrawSegments (dpy, d, p->gc, seg, nseg);
}

void
StringSize (s, xw, yw)
char  *s;
int   *xw, *yw;
{

      *xw = XTextWidth (app_data.ruler_font, s, strlen (s));
      *yw = app_data.ruler_font->max_bounds.ascent;

}

Generated by  Doxygen 1.6.0   Back to index