File: x_box.c

package info (click to toggle)
plotutils 2.0-2
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 5,964 kB
  • ctags: 2,522
  • sloc: ansic: 38,416; sh: 1,853; yacc: 856; makefile: 181; lex: 144
file content (104 lines) | stat: -rw-r--r-- 3,071 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* This file contains the box method, which is a standard part of libplot.
   It draws an object: an upright rectangle with diagonal corners x0,y0 and
   x1,y1. */

#include "sys-defines.h"
#include "plot.h"
#include "extern.h"

int
#ifdef _HAVE_PROTOS
_x_fbox (double x0, double y0, double x1, double y1)
#else
_x_fbox (x0, y0, x1, y1)
     double x0, y0, x1, y1;
#endif
{
  unsigned int width, height;
  int xdmin, xdmax, ydmin, ydmax;
  int xd0, xd1, yd0, yd1;
  double xnew, ynew;

  if (!_plotter->open)
    {
      _plotter->error ("fbox: invalid operation");
      return -1;
    }

  /* if user coors -> device coors transformation does not preserve axis
     directions, use generic method rather than using the native X
     rectangle-drawing facility (which aligns boxes with the axes) */
  if (!_plotter->drawstate->transform.axes_preserved)
    return _g_fbox (x0, y0, x1, y1);

  _plotter->endpath (); /* flush polyline if any */

  xd0 = IROUND(XD (x0, y0));
  yd0 = IROUND(YD (x0, y0));  
  xd1 = IROUND(XD (x1, y1));
  yd1 = IROUND(YD (x1, y1));  

  xdmin = IMIN (xd0, xd1);
  ydmin = IMIN (yd0, yd1);
  xdmax = IMAX (xd0, xd1);
  ydmax = IMAX (yd0, yd1);

  width = (unsigned int)(xdmax - xdmin);
  height = (unsigned int)(ydmax - ydmin);
  
  if (XOOB_INT(xdmin) || XOOB_INT(ydmin) 
      || XOOB_UNSIGNED(width) || XOOB_UNSIGNED(height))
    return -1;

  /* should check for width, height being 0 here, and treat this special
     case appropriately: FIXME */

  /* Semantics of XDrawRectangle() and XFillRectangle() are as follows.  To
     draw a 10x10 rectangle, the boundary of the rectangular region
     [0,9]x[0,9], XDrawRectangle() should be called with arguments 0,0,9,9.
     But to paint each pixel in [0,9]x[0,9], XFillRectangle() should be
     called with args 0,0,10,10.

     We don't bother incrementing the args of XFillRectangle, because we
     follow our XFillRectangle() by an XDrawRectangle(). */

  /* place current line attributes in the X GC */
  _plotter->set_attributes();  

  if (_plotter->drawstate->fill_level)	/* not transparent */
    {
      /* select fill color as X foreground color */
      _plotter->set_fill_color();

      if (_plotter->drawable1)
	XFillRectangle (_plotter->dpy, _plotter->drawable1, 
			_plotter->drawstate->gc, 
			xdmin, ydmin, width, height);
      if (_plotter->drawable2)
	XFillRectangle (_plotter->dpy, _plotter->drawable2, 
			_plotter->drawstate->gc, 
			xdmin, ydmin, width, height);
    }

  /* select pen color as X foreground color */
  _plotter->set_pen_color();

  if (_plotter->drawable1)
    XDrawRectangle (_plotter->dpy, _plotter->drawable1, 
		    _plotter->drawstate->gc, 
		    xdmin, ydmin, width, height);
  if (_plotter->drawable2)
    XDrawRectangle (_plotter->dpy, _plotter->drawable2, 
		    _plotter->drawstate->gc, 
		    xdmin, ydmin, width, height);

  /* move to center (libplot convention) */
  xnew = 0.5 * (x0 + x1);
  ynew = 0.5 * (y0 + y1);
  _plotter->drawstate->pos.x = xnew;
  _plotter->drawstate->pos.y = ynew;

  _handle_x_events();

  return 0;
}