2 /* Copyright (C) 1989, 1990, 1991, 1992, 2003 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.com)
5 This file is part of groff.
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with groff; see the file COPYING. If not, write to the Free Software
19 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
24 // output a dashed circle as a series of arcs
26 void common_output::dashed_circle(const position
¢
, double rad
,
29 assert(lt
.type
== line_type::dashed
);
31 slt
.type
= line_type::solid
;
32 double dash_angle
= lt
.dash_width
/rad
;
35 if (dash_angle
>= M_PI
/4.0) {
36 if (dash_angle
< M_PI
/2.0) {
37 gap_angle
= M_PI
/2.0 - dash_angle
;
40 else if (dash_angle
< M_PI
) {
41 gap_angle
= M_PI
- dash_angle
;
45 circle(cent
, rad
, slt
, -1.0);
50 ndashes
= 4*int(ceil(M_PI
/(4.0*dash_angle
)));
51 gap_angle
= (M_PI
*2.0)/ndashes
- dash_angle
;
53 for (int i
= 0; i
< ndashes
; i
++) {
54 double start_angle
= i
*(dash_angle
+gap_angle
) - dash_angle
/2.0;
55 solid_arc(cent
, rad
, start_angle
, start_angle
+ dash_angle
, lt
);
59 // output a dotted circle as a series of dots
61 void common_output::dotted_circle(const position
¢
, double rad
,
64 assert(lt
.type
== line_type::dotted
);
65 double gap_angle
= lt
.dash_width
/rad
;
67 if (gap_angle
>= M_PI
/2.0) {
68 // always have at least 2 dots
73 ndots
= 4*int(M_PI
/(2.0*gap_angle
));
74 gap_angle
= (M_PI
*2.0)/ndots
;
77 for (int i
= 0; i
< ndots
; i
++, ang
+= gap_angle
)
78 dot(cent
+ position(cos(ang
), sin(ang
))*rad
, lt
);
81 // recursive function for dash drawing, used by dashed_ellipse
83 void common_output::ellipse_arc(const position
¢
,
84 const position
&z0
, const position
&z1
,
85 const distance
&dim
, const line_type
<
)
87 assert(lt
.type
== line_type::solid
);
88 assert(dim
.x
!= 0 && dim
.y
!= 0);
90 position zml
= (z0
+ z1
) / 2;
91 // apply affine transformation (from ellipse to circle) to compute angle
92 // of new position, then invert transformation to get exact position
93 double psi
= atan2(zml
.y
/ dim
.y
, zml
.x
/ dim
.x
);
94 position zm
= position(dim
.x
* cos(psi
), dim
.y
* sin(psi
));
95 // to approximate the ellipse arc with one or more circle arcs, we
96 // first compute the radius of curvature in zm
97 double a_2
= dim
.x
* dim
.x
;
98 double a_4
= a_2
* a_2
;
99 double b_2
= dim
.y
* dim
.y
;
100 double b_4
= b_2
* b_2
;
101 double e_2
= a_2
- b_2
;
102 double temp
= a_4
* zm
.y
* zm
.y
+ b_4
* zm
.x
* zm
.x
;
103 double rho
= sqrt(temp
/ a_4
/ b_4
* temp
/ a_4
/ b_4
* temp
);
104 // compute center of curvature circle
105 position M
= position(e_2
* zm
.x
/ a_2
* zm
.x
/ a_2
* zm
.x
,
106 -e_2
* zm
.y
/ b_2
* zm
.y
/ b_2
* zm
.y
);
107 // compute distance between circle and ellipse arc at start and end
108 double phi0
= atan2(z0
.y
- M
.y
, z0
.x
- M
.x
);
109 double phi1
= atan2(z1
.y
- M
.y
, z1
.x
- M
.x
);
110 position M0
= position(rho
* cos(phi0
), rho
* sin(phi0
)) + M
;
111 position M1
= position(rho
* cos(phi1
), rho
* sin(phi1
)) + M
;
112 double dist0
= hypot(z0
- M0
) / sqrt(z0
* z0
);
113 double dist1
= hypot(z1
- M1
) / sqrt(z1
* z1
);
114 if (dist0
< eps
&& dist1
< eps
)
115 solid_arc(M
+ cent
, rho
, phi0
, phi1
, lt
);
117 ellipse_arc(cent
, z0
, zm
, dim
, lt
);
118 ellipse_arc(cent
, zm
, z1
, dim
, lt
);
122 // output a dashed ellipse as a series of arcs
124 void common_output::dashed_ellipse(const position
¢
, const distance
&dim
,
127 assert(lt
.type
== line_type::dashed
);
128 double dim_x
= dim
.x
/ 2;
129 double dim_y
= dim
.y
/ 2;
131 slt
.type
= line_type::solid
;
132 double dw
= lt
.dash_width
;
133 // we use an approximation to compute the ellipse length (found in:
134 // Bronstein, Semendjajew, Taschenbuch der Mathematik)
135 double lambda
= (dim
.x
- dim
.y
) / (dim
.x
+ dim
.y
);
136 double le
= M_PI
/ 2 * (dim
.x
+ dim
.y
)
137 * ((64 - 3 * lambda
* lambda
* lambda
* lambda
)
138 / (64 - 16 * lambda
* lambda
));
139 // for symmetry we make nmax a multiple of 8
140 int nmax
= 8 * int(le
/ dw
/ 8 + 0.5);
145 int ndash
= nmax
/ 2;
146 double gapwidth
= (le
- dw
* ndash
) / ndash
;
148 position z
= position(dim_x
, 0);
151 int jmax
= int(10 / lt
.dash_width
);
152 for (int i
= 0; i
<= nmax
; i
++) {
154 position zpre
= zdot
;
155 double ld
= (int(i
/ 2) + 0.5) * dw
+ int((i
+ 1) / 2) * gapwidth
;
158 // find next position for fixed arc length
163 double phi
= j
* 2 * M_PI
/ jmax
;
164 z
= position(dim_x
* cos(phi
), dim_y
* sin(phi
));
165 dl
= hypot(z
- zold
);
168 // interpolate linearly between the last two points,
169 // using the length difference as the scaling factor
170 double delta
= (ld
- lold
) / dl
;
171 zdot
= zold
+ (z
- zold
) * delta
;
172 // compute angle of new position on the affine circle
173 // and use it to get the exact value on the ellipse
174 double psi
= atan2(zdot
.y
/ dim_y
, zdot
.x
/ dim_x
);
175 zdot
= position(dim_x
* cos(psi
), dim_y
* sin(psi
));
176 if ((i
% 2 == 0) && (i
> 1))
177 ellipse_arc(cent
, zpre
, zdot
, dim
/ 2, slt
);
181 // output a dotted ellipse as a series of dots
183 void common_output::dotted_ellipse(const position
¢
, const distance
&dim
,
186 assert(lt
.type
== line_type::dotted
);
187 double dim_x
= dim
.x
/ 2;
188 double dim_y
= dim
.y
/ 2;
190 slt
.type
= line_type::solid
;
191 // we use an approximation to compute the ellipse length (found in:
192 // Bronstein, Semendjajew, Taschenbuch der Mathematik)
193 double lambda
= (dim
.x
- dim
.y
) / (dim
.x
+ dim
.y
);
194 double le
= M_PI
/ 2 * (dim
.x
+ dim
.y
)
195 * ((64 - 3 * lambda
* lambda
* lambda
* lambda
)
196 / (64 - 16 * lambda
* lambda
));
197 // for symmetry we make nmax a multiple of 4
198 int ndots
= 4 * int(le
/ lt
.dash_width
/ 4 + 0.5);
202 position z
= position(dim_x
, 0);
204 int jmax
= int(10 / lt
.dash_width
);
205 for (int i
= 1; i
<= ndots
; i
++) {
208 double ld
= i
* le
/ ndots
;
210 // find next position for fixed arc length
215 double phi
= j
* 2 * M_PI
/ jmax
;
216 z
= position(dim_x
* cos(phi
), dim_y
* sin(phi
));
217 dl
= hypot(z
- zold
);
220 // interpolate linearly between the last two points,
221 // using the length difference as the scaling factor
222 double delta
= (ld
- lold
) / dl
;
223 position zdot
= zold
+ (z
- zold
) * delta
;
224 // compute angle of new position on the affine circle
225 // and use it to get the exact value on the ellipse
226 double psi
= atan2(zdot
.y
/ dim_y
, zdot
.x
/ dim_x
);
227 zdot
= position(dim_x
* cos(psi
), dim_y
* sin(psi
));
228 dot(cent
+ zdot
, slt
);
232 // return non-zero iff we can compute a center
234 int compute_arc_center(const position
&start
, const position
¢
,
235 const position
&end
, position
*result
)
237 // This finds the point along the vector from start to cent that
238 // is equidistant between start and end.
239 distance c
= cent
- start
;
240 distance e
= end
- start
;
244 *result
= start
+ c
*((e
*e
)/(2.0*n
));
248 // output a dashed arc as a series of arcs
250 void common_output::dashed_arc(const position
&start
, const position
¢
,
251 const position
&end
, const line_type
<
)
253 assert(lt
.type
== line_type::dashed
);
255 if (!compute_arc_center(start
, cent
, end
, &c
)) {
256 line(start
, &end
, 1, lt
);
259 distance start_offset
= start
- c
;
260 distance end_offset
= end
- c
;
261 double start_angle
= atan2(start_offset
.y
, start_offset
.x
);
262 double end_angle
= atan2(end_offset
.y
, end_offset
.x
);
263 double rad
= hypot(c
- start
);
264 double dash_angle
= lt
.dash_width
/rad
;
265 double total_angle
= end_angle
- start_angle
;
266 while (total_angle
< 0)
267 total_angle
+= M_PI
+ M_PI
;
268 if (total_angle
<= dash_angle
*2.0) {
269 solid_arc(cent
, rad
, start_angle
, end_angle
, lt
);
272 int ndashes
= int((total_angle
- dash_angle
)/(dash_angle
*2.0) + .5);
273 double dash_and_gap_angle
= (total_angle
- dash_angle
)/ndashes
;
274 for (int i
= 0; i
<= ndashes
; i
++)
275 solid_arc(cent
, rad
, start_angle
+ i
*dash_and_gap_angle
,
276 start_angle
+ i
*dash_and_gap_angle
+ dash_angle
, lt
);
279 // output a dotted arc as a series of dots
281 void common_output::dotted_arc(const position
&start
, const position
¢
,
282 const position
&end
, const line_type
<
)
284 assert(lt
.type
== line_type::dotted
);
286 if (!compute_arc_center(start
, cent
, end
, &c
)) {
287 line(start
, &end
, 1, lt
);
290 distance start_offset
= start
- c
;
291 distance end_offset
= end
- c
;
292 double start_angle
= atan2(start_offset
.y
, start_offset
.x
);
293 double total_angle
= atan2(end_offset
.y
, end_offset
.x
) - start_angle
;
294 while (total_angle
< 0)
295 total_angle
+= M_PI
+ M_PI
;
296 double rad
= hypot(c
- start
);
297 int ndots
= int(total_angle
/(lt
.dash_width
/rad
) + .5);
301 for (int i
= 0; i
<= ndots
; i
++) {
302 double a
= start_angle
+ (total_angle
*i
)/ndots
;
303 dot(cent
+ position(cos(a
), sin(a
))*rad
, lt
);
308 void common_output::solid_arc(const position
¢
, double rad
,
309 double start_angle
, double end_angle
,
313 slt
.type
= line_type::solid
;
314 arc(cent
+ position(cos(start_angle
), sin(start_angle
))*rad
,
316 cent
+ position(cos(end_angle
), sin(end_angle
))*rad
,
321 void common_output::rounded_box(const position
¢
, const distance
&dim
,
322 double rad
, const line_type
<
, double fill
)
325 filled_rounded_box(cent
, dim
, rad
, fill
);
327 case line_type::invisible
:
329 case line_type::dashed
:
330 dashed_rounded_box(cent
, dim
, rad
, lt
);
332 case line_type::dotted
:
333 dotted_rounded_box(cent
, dim
, rad
, lt
);
335 case line_type::solid
:
336 solid_rounded_box(cent
, dim
, rad
, lt
);
344 void common_output::dashed_rounded_box(const position
¢
,
345 const distance
&dim
, double rad
,
349 slt
.type
= line_type::solid
;
351 double hor_length
= dim
.x
+ (M_PI
/2.0 - 2.0)*rad
;
352 int n_hor_dashes
= int(hor_length
/(lt
.dash_width
*2.0) + .5);
353 double hor_gap_width
= (n_hor_dashes
!= 0
354 ? hor_length
/n_hor_dashes
- lt
.dash_width
357 double vert_length
= dim
.y
+ (M_PI
/2.0 - 2.0)*rad
;
358 int n_vert_dashes
= int(vert_length
/(lt
.dash_width
*2.0) + .5);
359 double vert_gap_width
= (n_vert_dashes
!= 0
360 ? vert_length
/n_vert_dashes
- lt
.dash_width
362 // Note that each corner arc has to be split into two for dashing,
363 // because one part is dashed using vert_gap_width, and the other
364 // using hor_gap_width.
365 double offset
= lt
.dash_width
/2.0;
366 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
367 -M_PI
/4.0, 0, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
368 dash_line(cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
),
369 cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
),
370 slt
, lt
.dash_width
, vert_gap_width
, &offset
);
371 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
372 0, M_PI
/4.0, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
374 offset
= lt
.dash_width
/2.0;
375 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
376 M_PI
/4.0, M_PI
/2, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
377 dash_line(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0),
378 cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0),
379 slt
, lt
.dash_width
, hor_gap_width
, &offset
);
380 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
381 M_PI
/2, 3*M_PI
/4.0, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
383 offset
= lt
.dash_width
/2.0;
384 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
385 3.0*M_PI
/4.0, M_PI
, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
386 dash_line(cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
),
387 cent
+ position(-dim
.x
/2.0, -dim
.y
/2.0 + rad
),
388 slt
, lt
.dash_width
, vert_gap_width
, &offset
);
389 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
390 M_PI
, 5.0*M_PI
/4.0, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
392 offset
= lt
.dash_width
/2.0;
393 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
394 5*M_PI
/4.0, 3*M_PI
/2.0, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
395 dash_line(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0),
396 cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0),
397 slt
, lt
.dash_width
, hor_gap_width
, &offset
);
398 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
399 3*M_PI
/2, 7*M_PI
/4, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
402 // Used by dashed_rounded_box.
404 void common_output::dash_arc(const position
¢
, double rad
,
405 double start_angle
, double end_angle
,
407 double dash_width
, double gap_width
,
410 double length
= (end_angle
- start_angle
)*rad
;
413 if (*offsetp
>= dash_width
) {
414 double rem
= dash_width
+ gap_width
- *offsetp
;
415 if (pos
+ rem
> length
) {
416 *offsetp
+= length
- pos
;
425 double rem
= dash_width
- *offsetp
;
426 if (pos
+ rem
> length
) {
427 solid_arc(cent
, rad
, start_angle
+ pos
/rad
, end_angle
, lt
);
428 *offsetp
+= length
- pos
;
432 solid_arc(cent
, rad
, start_angle
+ pos
/rad
,
433 start_angle
+ (pos
+ rem
)/rad
, lt
);
435 *offsetp
= dash_width
;
441 // Used by dashed_rounded_box.
443 void common_output::dash_line(const position
&start
, const position
&end
,
445 double dash_width
, double gap_width
,
448 distance dist
= end
- start
;
449 double length
= hypot(dist
);
454 if (*offsetp
>= dash_width
) {
455 double rem
= dash_width
+ gap_width
- *offsetp
;
456 if (pos
+ rem
> length
) {
457 *offsetp
+= length
- pos
;
466 double rem
= dash_width
- *offsetp
;
467 if (pos
+ rem
> length
) {
468 line(start
+ dist
*(pos
/length
), &end
, 1, lt
);
469 *offsetp
+= length
- pos
;
473 position
p(start
+ dist
*((pos
+ rem
)/length
));
474 line(start
+ dist
*(pos
/length
), &p
, 1, lt
);
476 *offsetp
= dash_width
;
482 void common_output::dotted_rounded_box(const position
¢
,
483 const distance
&dim
, double rad
,
487 slt
.type
= line_type::solid
;
489 double hor_length
= dim
.x
+ (M_PI
/2.0 - 2.0)*rad
;
490 int n_hor_dots
= int(hor_length
/lt
.dash_width
+ .5);
491 double hor_gap_width
= (n_hor_dots
!= 0
492 ? hor_length
/n_hor_dots
495 double vert_length
= dim
.y
+ (M_PI
/2.0 - 2.0)*rad
;
496 int n_vert_dots
= int(vert_length
/lt
.dash_width
+ .5);
497 double vert_gap_width
= (n_vert_dots
!= 0
498 ? vert_length
/n_vert_dots
500 double epsilon
= lt
.dash_width
/(rad
*100.0);
503 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
504 -M_PI
/4.0, 0, slt
, vert_gap_width
, &offset
);
505 dot_line(cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
),
506 cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
),
507 slt
, vert_gap_width
, &offset
);
508 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
509 0, M_PI
/4.0 - epsilon
, slt
, vert_gap_width
, &offset
);
512 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
513 M_PI
/4.0, M_PI
/2, slt
, hor_gap_width
, &offset
);
514 dot_line(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0),
515 cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0),
516 slt
, hor_gap_width
, &offset
);
517 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
518 M_PI
/2, 3*M_PI
/4.0 - epsilon
, slt
, hor_gap_width
, &offset
);
521 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
522 3.0*M_PI
/4.0, M_PI
, slt
, vert_gap_width
, &offset
);
523 dot_line(cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
),
524 cent
+ position(-dim
.x
/2.0, -dim
.y
/2.0 + rad
),
525 slt
, vert_gap_width
, &offset
);
526 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
527 M_PI
, 5.0*M_PI
/4.0 - epsilon
, slt
, vert_gap_width
, &offset
);
530 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
531 5*M_PI
/4.0, 3*M_PI
/2.0, slt
, hor_gap_width
, &offset
);
532 dot_line(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0),
533 cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0),
534 slt
, hor_gap_width
, &offset
);
535 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
536 3*M_PI
/2, 7*M_PI
/4 - epsilon
, slt
, hor_gap_width
, &offset
);
539 // Used by dotted_rounded_box.
541 void common_output::dot_arc(const position
¢
, double rad
,
542 double start_angle
, double end_angle
,
543 const line_type
<
, double gap_width
,
546 double length
= (end_angle
- start_angle
)*rad
;
549 if (*offsetp
== 0.0) {
550 double ang
= start_angle
+ pos
/rad
;
551 dot(cent
+ position(cos(ang
), sin(ang
))*rad
, lt
);
553 double rem
= gap_width
- *offsetp
;
554 if (pos
+ rem
> length
) {
555 *offsetp
+= length
- pos
;
565 // Used by dotted_rounded_box.
567 void common_output::dot_line(const position
&start
, const position
&end
,
568 const line_type
<
, double gap_width
,
571 distance dist
= end
- start
;
572 double length
= hypot(dist
);
578 dot(start
+ dist
*(pos
/length
), lt
);
579 double rem
= gap_width
- *offsetp
;
580 if (pos
+ rem
> length
) {
581 *offsetp
+= length
- pos
;
591 void common_output::solid_rounded_box(const position
¢
,
592 const distance
&dim
, double rad
,
595 position tem
= cent
- dim
/2.0;
596 arc(tem
+ position(0.0, rad
),
597 tem
+ position(rad
, rad
),
598 tem
+ position(rad
, 0.0),
600 tem
= cent
+ position(-dim
.x
/2.0, dim
.y
/2.0);
601 arc(tem
+ position(rad
, 0.0),
602 tem
+ position(rad
, -rad
),
603 tem
+ position(0.0, -rad
),
605 tem
= cent
+ dim
/2.0;
606 arc(tem
+ position(0.0, -rad
),
607 tem
+ position(-rad
, -rad
),
608 tem
+ position(-rad
, 0.0),
610 tem
= cent
+ position(dim
.x
/2.0, -dim
.y
/2.0);
611 arc(tem
+ position(-rad
, 0.0),
612 tem
+ position(-rad
, rad
),
613 tem
+ position(0.0, rad
),
616 end
= cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
);
617 line(cent
- dim
/2.0 + position(0.0, rad
), &end
, 1, lt
);
618 end
= cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0);
619 line(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0), &end
, 1, lt
);
620 end
= cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
);
621 line(cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
), &end
, 1, lt
);
622 end
= cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0);
623 line(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0), &end
, 1, lt
);
626 void common_output::filled_rounded_box(const position
¢
,
627 const distance
&dim
, double rad
,
631 ilt
.type
= line_type::invisible
;
632 circle(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
, ilt
, fill
);
633 circle(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
, ilt
, fill
);
634 circle(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
, ilt
, fill
);
635 circle(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
, ilt
, fill
);
637 vec
[0] = cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
);
638 vec
[1] = cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
);
639 vec
[2] = cent
+ position(-dim
.x
/2.0, -dim
.y
/2.0 + rad
);
640 vec
[3] = cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
);
641 polygon(vec
, 4, ilt
, fill
);
642 vec
[0] = cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0);
643 vec
[1] = cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0);
644 vec
[2] = cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0);
645 vec
[3] = cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0);
646 polygon(vec
, 4, ilt
, fill
);