common.cpp revision 114402
1114402Sru// -*- C++ -*-
2114402Sru/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
3114402Sru     Written by James Clark (jjc@jclark.com)
4114402Sru
5114402SruThis file is part of groff.
6114402Sru
7114402Srugroff is free software; you can redistribute it and/or modify it under
8114402Sruthe terms of the GNU General Public License as published by the Free
9114402SruSoftware Foundation; either version 2, or (at your option) any later
10114402Sruversion.
11114402Sru
12114402Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
13114402SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
14114402SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15114402Srufor more details.
16114402Sru
17114402SruYou should have received a copy of the GNU General Public License along
18114402Sruwith groff; see the file COPYING.  If not, write to the Free Software
19114402SruFoundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20114402Sru
21114402Sru#include "pic.h"
22114402Sru#include "common.h"
23114402Sru
24114402Sru// output a dashed circle as a series of arcs
25114402Sru
26114402Sruvoid common_output::dashed_circle(const position &cent, double rad,
27114402Sru				  const line_type &lt)
28114402Sru{
29114402Sru  assert(lt.type == line_type::dashed);
30114402Sru  line_type slt = lt;
31114402Sru  slt.type = line_type::solid;
32114402Sru  double dash_angle = lt.dash_width/rad;
33114402Sru  int ndashes;
34114402Sru  double gap_angle;
35114402Sru  if (dash_angle >= M_PI/4.0) {
36114402Sru    if (dash_angle < M_PI/2.0) {
37114402Sru      gap_angle = M_PI/2.0 - dash_angle;
38114402Sru      ndashes = 4;
39114402Sru    }
40114402Sru    else if (dash_angle < M_PI) {
41114402Sru      gap_angle = M_PI - dash_angle;
42114402Sru      ndashes = 2;
43114402Sru    }
44114402Sru    else {
45114402Sru      circle(cent, rad, slt, -1.0);
46114402Sru      return;
47114402Sru    }
48114402Sru  }
49114402Sru  else {
50114402Sru    ndashes = 4*int(ceil(M_PI/(4.0*dash_angle)));
51114402Sru    gap_angle = (M_PI*2.0)/ndashes - dash_angle;
52114402Sru  }
53114402Sru  for (int i = 0; i < ndashes; i++) {
54114402Sru    double start_angle = i*(dash_angle+gap_angle) - dash_angle/2.0;
55114402Sru    solid_arc(cent, rad, start_angle, start_angle + dash_angle, lt);
56114402Sru  }
57114402Sru}
58114402Sru
59114402Sru// output a dotted circle as a series of dots
60114402Sru
61114402Sruvoid common_output::dotted_circle(const position &cent, double rad,
62114402Sru				  const line_type &lt)
63114402Sru{
64114402Sru  assert(lt.type == line_type::dotted);
65114402Sru  double gap_angle = lt.dash_width/rad;
66114402Sru  int ndots;
67114402Sru  if (gap_angle >= M_PI/2.0) {
68114402Sru    // always have at least 2 dots
69114402Sru    gap_angle = M_PI;
70114402Sru    ndots = 2;
71114402Sru  }
72114402Sru  else {
73114402Sru    ndots = 4*int(M_PI/(2.0*gap_angle));
74114402Sru    gap_angle = (M_PI*2.0)/ndots;
75114402Sru  }
76114402Sru  double ang = 0.0;
77114402Sru  for (int i = 0; i < ndots; i++, ang += gap_angle)
78114402Sru    dot(cent + position(cos(ang), sin(ang))*rad, lt);
79114402Sru}
80114402Sru
81114402Sru// return non-zero iff we can compute a center
82114402Sru
83114402Sruint compute_arc_center(const position &start, const position &cent,
84114402Sru		       const position &end, position *result)
85114402Sru{
86114402Sru  // This finds the point along the vector from start to cent that
87114402Sru  // is equidistant between start and end.
88114402Sru  distance c = cent - start;
89114402Sru  distance e = end - start;
90114402Sru  double n = c*e;
91114402Sru  if (n == 0.0)
92114402Sru    return 0;
93114402Sru  *result = start + c*((e*e)/(2.0*n));
94114402Sru  return 1;
95114402Sru}
96114402Sru
97114402Sru// output a dashed arc as a series of arcs
98114402Sru
99114402Sruvoid common_output::dashed_arc(const position &start, const position &cent,
100114402Sru			       const position &end, const line_type &lt)
101114402Sru{
102114402Sru  assert(lt.type == line_type::dashed);
103114402Sru  position c;
104114402Sru  if (!compute_arc_center(start, cent, end, &c)) {
105114402Sru    line(start, &end, 1, lt);
106114402Sru    return;
107114402Sru  }
108114402Sru  distance start_offset = start - c;
109114402Sru  distance end_offset = end - c;
110114402Sru  double start_angle = atan2(start_offset.y, start_offset.x);
111114402Sru  double end_angle = atan2(end_offset.y, end_offset.x);
112114402Sru  double rad = hypot(c - start);
113114402Sru  double dash_angle = lt.dash_width/rad;
114114402Sru  double total_angle = end_angle - start_angle;
115114402Sru  while (total_angle < 0)
116114402Sru    total_angle += M_PI + M_PI;
117114402Sru  if (total_angle <= dash_angle*2.0) {
118114402Sru    solid_arc(cent, rad, start_angle, end_angle, lt);
119114402Sru    return;
120114402Sru  }
121114402Sru  int ndashes = int((total_angle - dash_angle)/(dash_angle*2.0) + .5);
122114402Sru  double dash_and_gap_angle = (total_angle - dash_angle)/ndashes;
123114402Sru  for (int i = 0; i <= ndashes; i++)
124114402Sru    solid_arc(cent, rad, start_angle + i*dash_and_gap_angle,
125114402Sru	      start_angle + i*dash_and_gap_angle + dash_angle, lt);
126114402Sru}
127114402Sru
128114402Sru// output a dotted arc as a series of dots
129114402Sru
130114402Sruvoid common_output::dotted_arc(const position &start, const position &cent,
131114402Sru			       const position &end, const line_type &lt)
132114402Sru{
133114402Sru  assert(lt.type == line_type::dotted);
134114402Sru  position c;
135114402Sru  if (!compute_arc_center(start, cent, end, &c)) {
136114402Sru    line(start, &end, 1, lt);
137114402Sru    return;
138114402Sru  }
139114402Sru  distance start_offset = start - c;
140114402Sru  distance end_offset = end - c;
141114402Sru  double start_angle = atan2(start_offset.y, start_offset.x);
142114402Sru  double total_angle = atan2(end_offset.y, end_offset.x) - start_angle;
143114402Sru  while (total_angle < 0)
144114402Sru    total_angle += M_PI + M_PI;
145114402Sru  double rad = hypot(c - start);
146114402Sru  int ndots = int(total_angle/(lt.dash_width/rad) + .5);
147114402Sru  if (ndots == 0)
148114402Sru    dot(start, lt);
149114402Sru  else {
150114402Sru    for (int i = 0; i <= ndots; i++) {
151114402Sru      double a = start_angle + (total_angle*i)/ndots;
152114402Sru      dot(cent + position(cos(a), sin(a))*rad, lt);
153114402Sru    }
154114402Sru  }
155114402Sru}
156114402Sru
157114402Sruvoid common_output::solid_arc(const position &cent, double rad,
158114402Sru			      double start_angle, double end_angle,
159114402Sru			      const line_type &lt)
160114402Sru{
161114402Sru  line_type slt = lt;
162114402Sru  slt.type = line_type::solid;
163114402Sru  arc(cent + position(cos(start_angle), sin(start_angle))*rad,
164114402Sru      cent,
165114402Sru      cent + position(cos(end_angle), sin(end_angle))*rad,
166114402Sru      slt);
167114402Sru}
168114402Sru
169114402Sru
170114402Sruvoid common_output::rounded_box(const position &cent, const distance &dim,
171114402Sru				double rad, const line_type &lt, double fill)
172114402Sru{
173114402Sru  if (fill >= 0.0)
174114402Sru    filled_rounded_box(cent, dim, rad, fill);
175114402Sru  switch (lt.type) {
176114402Sru  case line_type::invisible:
177114402Sru    break;
178114402Sru  case line_type::dashed:
179114402Sru    dashed_rounded_box(cent, dim, rad, lt);
180114402Sru    break;
181114402Sru  case line_type::dotted:
182114402Sru    dotted_rounded_box(cent, dim, rad, lt);
183114402Sru    break;
184114402Sru  case line_type::solid:
185114402Sru    solid_rounded_box(cent, dim, rad, lt);
186114402Sru    break;
187114402Sru  default:
188114402Sru    assert(0);
189114402Sru  }
190114402Sru}
191114402Sru
192114402Sru
193114402Sruvoid common_output::dashed_rounded_box(const position &cent,
194114402Sru				       const distance &dim, double rad,
195114402Sru				       const line_type &lt)
196114402Sru{
197114402Sru  line_type slt = lt;
198114402Sru  slt.type = line_type::solid;
199114402Sru
200114402Sru  double hor_length = dim.x + (M_PI/2.0 - 2.0)*rad;
201114402Sru  int n_hor_dashes = int(hor_length/(lt.dash_width*2.0) + .5);
202114402Sru  double hor_gap_width = (n_hor_dashes != 0
203114402Sru			  ? hor_length/n_hor_dashes - lt.dash_width
204114402Sru			  : 0.0);
205114402Sru
206114402Sru  double vert_length = dim.y + (M_PI/2.0 - 2.0)*rad;
207114402Sru  int n_vert_dashes = int(vert_length/(lt.dash_width*2.0) + .5);
208114402Sru  double vert_gap_width = (n_vert_dashes != 0
209114402Sru			   ? vert_length/n_vert_dashes - lt.dash_width
210114402Sru			   : 0.0);
211114402Sru  // Note that each corner arc has to be split into two for dashing,
212114402Sru  // because one part is dashed using vert_gap_width, and the other
213114402Sru  // using hor_gap_width.
214114402Sru  double offset = lt.dash_width/2.0;
215114402Sru  dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,
216114402Sru	   -M_PI/4.0, 0, slt, lt.dash_width, vert_gap_width, &offset);
217114402Sru  dash_line(cent + position(dim.x/2.0, -dim.y/2.0 + rad),
218114402Sru	    cent + position(dim.x/2.0, dim.y/2.0 - rad),
219114402Sru	    slt, lt.dash_width, vert_gap_width, &offset);
220114402Sru  dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,
221114402Sru	   0, M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset);
222114402Sru
223114402Sru  offset = lt.dash_width/2.0;
224114402Sru  dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,
225114402Sru	   M_PI/4.0, M_PI/2, slt, lt.dash_width, hor_gap_width, &offset);
226114402Sru  dash_line(cent + position(dim.x/2.0 - rad, dim.y/2.0),
227114402Sru	    cent + position(-dim.x/2.0 + rad, dim.y/2.0),
228114402Sru	    slt, lt.dash_width, hor_gap_width, &offset);
229114402Sru  dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,
230114402Sru	   M_PI/2, 3*M_PI/4.0, slt, lt.dash_width, hor_gap_width, &offset);
231114402Sru
232114402Sru  offset = lt.dash_width/2.0;
233114402Sru  dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,
234114402Sru	   3.0*M_PI/4.0, M_PI, slt, lt.dash_width, vert_gap_width, &offset);
235114402Sru  dash_line(cent + position(-dim.x/2.0, dim.y/2.0 - rad),
236114402Sru	    cent + position(-dim.x/2.0, -dim.y/2.0 + rad),
237114402Sru	    slt, lt.dash_width, vert_gap_width, &offset);
238114402Sru  dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,
239114402Sru	   M_PI, 5.0*M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset);
240114402Sru
241114402Sru  offset = lt.dash_width/2.0;
242114402Sru  dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,
243114402Sru	   5*M_PI/4.0, 3*M_PI/2.0, slt, lt.dash_width, hor_gap_width, &offset);
244114402Sru  dash_line(cent + position(-dim.x/2.0 + rad, -dim.y/2.0),
245114402Sru	    cent + position(dim.x/2.0 - rad, -dim.y/2.0),
246114402Sru	    slt, lt.dash_width, hor_gap_width, &offset);
247114402Sru  dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,
248114402Sru	   3*M_PI/2, 7*M_PI/4, slt, lt.dash_width, hor_gap_width, &offset);
249114402Sru}
250114402Sru
251114402Sru// Used by dashed_rounded_box.
252114402Sru
253114402Sruvoid common_output::dash_arc(const position &cent, double rad,
254114402Sru			     double start_angle, double end_angle,
255114402Sru			     const line_type &lt,
256114402Sru			     double dash_width, double gap_width,
257114402Sru			     double *offsetp)
258114402Sru{
259114402Sru  double length = (end_angle - start_angle)*rad;
260114402Sru  double pos = 0.0;
261114402Sru  for (;;) {
262114402Sru    if (*offsetp >= dash_width) {
263114402Sru      double rem = dash_width + gap_width - *offsetp;
264114402Sru      if (pos + rem > length) {
265114402Sru	*offsetp += length - pos;
266114402Sru	break;
267114402Sru      }
268114402Sru      else {
269114402Sru	pos += rem;
270114402Sru	*offsetp = 0.0;
271114402Sru      }
272114402Sru    }
273114402Sru    else {
274114402Sru      double rem = dash_width  - *offsetp;
275114402Sru      if (pos + rem > length) {
276114402Sru	solid_arc(cent, rad, start_angle + pos/rad, end_angle, lt);
277114402Sru	*offsetp += length - pos;
278114402Sru	break;
279114402Sru      }
280114402Sru      else {
281114402Sru	solid_arc(cent, rad, start_angle + pos/rad,
282114402Sru		  start_angle + (pos + rem)/rad, lt);
283114402Sru	pos += rem;
284114402Sru	*offsetp = dash_width;
285114402Sru      }
286114402Sru    }
287114402Sru  }
288114402Sru}
289114402Sru
290114402Sru// Used by dashed_rounded_box.
291114402Sru
292114402Sruvoid common_output::dash_line(const position &start, const position &end,
293114402Sru			      const line_type &lt,
294114402Sru			      double dash_width, double gap_width,
295114402Sru			      double *offsetp)
296114402Sru{
297114402Sru  distance dist = end - start;
298114402Sru  double length = hypot(dist);
299114402Sru  if (length == 0.0)
300114402Sru    return;
301114402Sru  double pos = 0.0;
302114402Sru  for (;;) {
303114402Sru    if (*offsetp >= dash_width) {
304114402Sru      double rem = dash_width + gap_width - *offsetp;
305114402Sru      if (pos + rem > length) {
306114402Sru	*offsetp += length - pos;
307114402Sru	break;
308114402Sru      }
309114402Sru      else {
310114402Sru	pos += rem;
311114402Sru	*offsetp = 0.0;
312114402Sru      }
313114402Sru    }
314114402Sru    else {
315114402Sru      double rem = dash_width  - *offsetp;
316114402Sru      if (pos + rem > length) {
317114402Sru	line(start + dist*(pos/length), &end, 1, lt);
318114402Sru	*offsetp += length - pos;
319114402Sru	break;
320114402Sru      }
321114402Sru      else {
322114402Sru	position p(start + dist*((pos + rem)/length));
323114402Sru	line(start + dist*(pos/length), &p, 1, lt);
324114402Sru	pos += rem;
325114402Sru	*offsetp = dash_width;
326114402Sru      }
327114402Sru    }
328114402Sru  }
329114402Sru}
330114402Sru
331114402Sruvoid common_output::dotted_rounded_box(const position &cent,
332114402Sru				       const distance &dim, double rad,
333114402Sru				       const line_type &lt)
334114402Sru{
335114402Sru  line_type slt = lt;
336114402Sru  slt.type = line_type::solid;
337114402Sru
338114402Sru  double hor_length = dim.x + (M_PI/2.0 - 2.0)*rad;
339114402Sru  int n_hor_dots = int(hor_length/lt.dash_width + .5);
340114402Sru  double hor_gap_width = (n_hor_dots != 0
341114402Sru			  ? hor_length/n_hor_dots
342114402Sru			  : lt.dash_width);
343114402Sru
344114402Sru  double vert_length = dim.y + (M_PI/2.0 - 2.0)*rad;
345114402Sru  int n_vert_dots = int(vert_length/lt.dash_width + .5);
346114402Sru  double vert_gap_width = (n_vert_dots != 0
347114402Sru			   ? vert_length/n_vert_dots
348114402Sru			   : lt.dash_width);
349114402Sru  double epsilon = lt.dash_width/(rad*100.0);
350114402Sru
351114402Sru  double offset = 0.0;
352114402Sru  dot_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,
353114402Sru	   -M_PI/4.0, 0, slt, vert_gap_width, &offset);
354114402Sru  dot_line(cent + position(dim.x/2.0, -dim.y/2.0 + rad),
355114402Sru	    cent + position(dim.x/2.0, dim.y/2.0 - rad),
356114402Sru	    slt, vert_gap_width, &offset);
357114402Sru  dot_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,
358114402Sru	   0, M_PI/4.0 - epsilon, slt, vert_gap_width, &offset);
359114402Sru
360114402Sru  offset = 0.0;
361114402Sru  dot_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,
362114402Sru	   M_PI/4.0, M_PI/2, slt, hor_gap_width, &offset);
363114402Sru  dot_line(cent + position(dim.x/2.0 - rad, dim.y/2.0),
364114402Sru	    cent + position(-dim.x/2.0 + rad, dim.y/2.0),
365114402Sru	    slt, hor_gap_width, &offset);
366114402Sru  dot_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,
367114402Sru	   M_PI/2, 3*M_PI/4.0 - epsilon, slt, hor_gap_width, &offset);
368114402Sru
369114402Sru  offset = 0.0;
370114402Sru  dot_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,
371114402Sru	   3.0*M_PI/4.0, M_PI, slt, vert_gap_width, &offset);
372114402Sru  dot_line(cent + position(-dim.x/2.0, dim.y/2.0 - rad),
373114402Sru	    cent + position(-dim.x/2.0, -dim.y/2.0 + rad),
374114402Sru	    slt, vert_gap_width, &offset);
375114402Sru  dot_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,
376114402Sru	   M_PI, 5.0*M_PI/4.0 - epsilon, slt, vert_gap_width, &offset);
377114402Sru
378114402Sru  offset = 0.0;
379114402Sru  dot_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,
380114402Sru	   5*M_PI/4.0, 3*M_PI/2.0, slt, hor_gap_width, &offset);
381114402Sru  dot_line(cent + position(-dim.x/2.0 + rad, -dim.y/2.0),
382114402Sru	    cent + position(dim.x/2.0 - rad, -dim.y/2.0),
383114402Sru	    slt, hor_gap_width, &offset);
384114402Sru  dot_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,
385114402Sru	   3*M_PI/2, 7*M_PI/4 - epsilon, slt, hor_gap_width, &offset);
386114402Sru}
387114402Sru
388114402Sru// Used by dotted_rounded_box.
389114402Sru
390114402Sruvoid common_output::dot_arc(const position &cent, double rad,
391114402Sru			    double start_angle, double end_angle,
392114402Sru			    const line_type &lt, double gap_width,
393114402Sru			    double *offsetp)
394114402Sru{
395114402Sru  double length = (end_angle - start_angle)*rad;
396114402Sru  double pos = 0.0;
397114402Sru  for (;;) {
398114402Sru    if (*offsetp == 0.0) {
399114402Sru      double ang = start_angle + pos/rad;
400114402Sru      dot(cent + position(cos(ang), sin(ang))*rad, lt);
401114402Sru    }
402114402Sru    double rem = gap_width - *offsetp;
403114402Sru    if (pos + rem > length) {
404114402Sru      *offsetp += length - pos;
405114402Sru      break;
406114402Sru    }
407114402Sru    else {
408114402Sru      pos += rem;
409114402Sru      *offsetp = 0.0;
410114402Sru    }
411114402Sru  }
412114402Sru}
413114402Sru
414114402Sru// Used by dotted_rounded_box.
415114402Sru
416114402Sruvoid common_output::dot_line(const position &start, const position &end,
417114402Sru			     const line_type &lt, double gap_width,
418114402Sru			     double *offsetp)
419114402Sru{
420114402Sru  distance dist = end - start;
421114402Sru  double length = hypot(dist);
422114402Sru  if (length == 0.0)
423114402Sru    return;
424114402Sru  double pos = 0.0;
425114402Sru  for (;;) {
426114402Sru    if (*offsetp == 0.0)
427114402Sru      dot(start + dist*(pos/length), lt);
428114402Sru    double rem = gap_width - *offsetp;
429114402Sru    if (pos + rem > length) {
430114402Sru      *offsetp += length - pos;
431114402Sru      break;
432114402Sru    }
433114402Sru    else {
434114402Sru      pos += rem;
435114402Sru      *offsetp = 0.0;
436114402Sru    }
437114402Sru  }
438114402Sru}
439114402Sru
440114402Sruvoid common_output::solid_rounded_box(const position &cent,
441114402Sru				      const distance &dim, double rad,
442114402Sru				      const line_type &lt)
443114402Sru{
444114402Sru  position tem = cent - dim/2.0;
445114402Sru  arc(tem + position(0.0, rad),
446114402Sru      tem + position(rad, rad),
447114402Sru      tem + position(rad, 0.0),
448114402Sru      lt);
449114402Sru  tem = cent + position(-dim.x/2.0, dim.y/2.0);
450114402Sru  arc(tem + position(rad, 0.0),
451114402Sru      tem + position(rad, -rad),
452114402Sru      tem + position(0.0, -rad),
453114402Sru      lt);
454114402Sru  tem = cent + dim/2.0;
455114402Sru  arc(tem + position(0.0, -rad),
456114402Sru      tem + position(-rad, -rad),
457114402Sru      tem + position(-rad, 0.0),
458114402Sru      lt);
459114402Sru  tem = cent + position(dim.x/2.0, -dim.y/2.0);
460114402Sru  arc(tem + position(-rad, 0.0),
461114402Sru      tem + position(-rad, rad),
462114402Sru      tem + position(0.0, rad),
463114402Sru      lt);
464114402Sru  position end;
465114402Sru  end = cent + position(-dim.x/2.0, dim.y/2.0 - rad);
466114402Sru  line(cent - dim/2.0 + position(0.0, rad), &end, 1, lt);
467114402Sru  end = cent + position(dim.x/2.0 - rad, dim.y/2.0);
468114402Sru  line(cent + position(-dim.x/2.0 + rad, dim.y/2.0), &end, 1, lt);
469114402Sru  end = cent + position(dim.x/2.0, -dim.y/2.0 + rad);
470114402Sru  line(cent + position(dim.x/2.0, dim.y/2.0 - rad), &end, 1, lt);
471114402Sru  end = cent + position(-dim.x/2.0 + rad, -dim.y/2.0);
472114402Sru  line(cent + position(dim.x/2.0 - rad, -dim.y/2.0), &end, 1, lt);
473114402Sru}
474114402Sru
475114402Sruvoid common_output::filled_rounded_box(const position &cent,
476114402Sru				       const distance &dim, double rad,
477114402Sru				       double fill)
478114402Sru{
479114402Sru  line_type ilt;
480114402Sru  ilt.type = line_type::invisible;
481114402Sru  circle(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, ilt, fill);
482114402Sru  circle(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, ilt, fill);
483114402Sru  circle(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, ilt, fill);
484114402Sru  circle(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, ilt, fill);
485114402Sru  position vec[4];
486114402Sru  vec[0] = cent + position(dim.x/2.0, dim.y/2.0 - rad);
487114402Sru  vec[1] = cent + position(-dim.x/2.0, dim.y/2.0 - rad);
488114402Sru  vec[2] = cent + position(-dim.x/2.0, -dim.y/2.0 + rad);
489114402Sru  vec[3] = cent + position(dim.x/2.0, -dim.y/2.0 + rad);
490114402Sru  polygon(vec, 4, ilt, fill);
491114402Sru  vec[0] = cent + position(dim.x/2.0 - rad, dim.y/2.0);
492114402Sru  vec[1] = cent + position(-dim.x/2.0 + rad, dim.y/2.0);
493114402Sru  vec[2] = cent + position(-dim.x/2.0 + rad, -dim.y/2.0);
494114402Sru  vec[3] = cent + position(dim.x/2.0 - rad, -dim.y/2.0);
495114402Sru  polygon(vec, 4, ilt, fill);
496114402Sru}
497