File: g_circ.c

package info (click to toggle)
plotutils 2.4.1-15
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 11,072 kB
  • ctags: 6,952
  • sloc: ansic: 76,305; cpp: 12,402; sh: 8,475; yacc: 2,604; makefile: 894; lex: 144
file content (103 lines) | stat: -rw-r--r-- 3,722 bytes parent folder | download | duplicates (3)
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
/* This file contains the circle method, which is a standard part of
   libplot.  It draws an object: a circle with center x,y and radius r.
   Circles are one of the three types of primitive closed path that libplot
   supports, along with boxes and ellipses. */

/* Most Plotters obviously require that the map from the user frame to the
   device frame be uniform, in order to draw a circle as a primitive (if it
   isn't, what results will be an ellipse).  The constraints on the user
   frame -> device frame map (e.g., it must be uniform) are specified by
   the internal `allowed_circle_scaling' parameter, which this code checks.  */

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

int
#ifdef _HAVE_PROTOS
_API_fcircle (R___(Plotter *_plotter) double x, double y, double r)
#else
_API_fcircle (R___(_plotter) x, y, r)
     S___(Plotter *_plotter;)
     double x, y, r;
#endif
{
  if (!_plotter->data->open)
    {
      _plotter->error (R___(_plotter) 
		       "fcircle: invalid operation");
      return -1;
    }

  /* If a simple path is under construction (so that endsubpath() must not
      have been invoked), flush out the whole compound path.  (It may
      include other, previously drawn simple paths.) */
  if (_plotter->drawstate->path)
    _API_endpath (S___(_plotter));

  if (!_plotter->drawstate->points_are_connected)
    /* line type is `disconnected', so do nothing (libplot convention) */
    {
    }

  else
    /* general case */
    {
      plPoint pc;
      bool clockwise;

      /* begin a new path */
      _plotter->drawstate->path = _new_plPath ();

      /* place circle in path buffer */

      pc.x = x;
      pc.y = y;
      clockwise = _plotter->drawstate->orientation < 0 ? true : false;

      if ((_plotter->data->allowed_circle_scaling == AS_ANY)
	  ||
	  (_plotter->data->allowed_circle_scaling == AS_UNIFORM
	   && _plotter->drawstate->transform.uniform))
	/* place circle as a primitive, since this Plotter supports
	   drawing circles as primitives */
	_add_circle (_plotter->drawstate->path, 
			       pc, r, clockwise);
      else if ((_plotter->data->allowed_ellipse_scaling == AS_ANY)
	       ||
	       (_plotter->data->allowed_ellipse_scaling == AS_AXES_PRESERVED
		&& _plotter->drawstate->transform.axes_preserved))
	/* place circle as an ellipse, since this Plotter supports drawing
	   ellipses as primitives */
	_add_ellipse (_plotter->drawstate->path, 
				pc, r, r, 0.0, clockwise);
      else if (_plotter->data->allowed_ellarc_scaling == AS_ANY
	       || (_plotter->data->allowed_ellarc_scaling == AS_AXES_PRESERVED
		   && _plotter->drawstate->transform.axes_preserved))
	/* draw circle by placing four elliptical arcs into path buffer
	   (allowed since this Plotter supports elliptical arcs) */
	_add_circle_as_ellarcs (_plotter->drawstate->path, 
				pc, r, clockwise);
      else if (_plotter->data->allowed_cubic_scaling == AS_ANY)
	/* draw circle by placing four cubic Beziers into path buffer
	   (allowed since this Plotter supports cubic Beziers) */
	_add_circle_as_bezier3s (_plotter->drawstate->path, 
				 pc, r, clockwise);
      else
	/* draw a polygonal approximation to the circle */
	_add_circle_as_lines (_plotter->drawstate->path, 
			      pc, r, clockwise);

      if (_plotter->drawstate->path->type == PATH_SEGMENT_LIST)
	/* pass all the newly added segments to the Plotter-specific
	   function maybe_paint_segments(), since some Plotters plot paths
	   in real time, i.e., prepaint them, rather than waiting until
	   endpath() is called */
	_plotter->maybe_prepaint_segments (R___(_plotter) 0);
    }

  /* move to center (libplot convention) */
  _plotter->drawstate->pos.x = x;
  _plotter->drawstate->pos.y = y;

  return 0;
}