4 /* Copyright (C) 1989, 1990, 1991, 1992, 2003 Free Software Foundation, Inc.
5 Written by James Clark (jjc@jclark.com)
7 This file is part of groff.
9 groff is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 groff is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License along
20 with groff; see the file COPYING. If not, write to the Free Software
21 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
26 // output a dashed circle as a series of arcs
28 void common_output::dashed_circle(const position
¢
, double rad
,
31 assert(lt
.type
== line_type::dashed
);
33 slt
.type
= line_type::solid
;
34 double dash_angle
= lt
.dash_width
/rad
;
37 if (dash_angle
>= M_PI
/4.0) {
38 if (dash_angle
< M_PI
/2.0) {
39 gap_angle
= M_PI
/2.0 - dash_angle
;
42 else if (dash_angle
< M_PI
) {
43 gap_angle
= M_PI
- dash_angle
;
47 circle(cent
, rad
, slt
, -1.0);
52 ndashes
= 4*int(ceil(M_PI
/(4.0*dash_angle
)));
53 gap_angle
= (M_PI
*2.0)/ndashes
- dash_angle
;
55 for (int i
= 0; i
< ndashes
; i
++) {
56 double start_angle
= i
*(dash_angle
+gap_angle
) - dash_angle
/2.0;
57 solid_arc(cent
, rad
, start_angle
, start_angle
+ dash_angle
, lt
);
61 // output a dotted circle as a series of dots
63 void common_output::dotted_circle(const position
¢
, double rad
,
66 assert(lt
.type
== line_type::dotted
);
67 double gap_angle
= lt
.dash_width
/rad
;
69 if (gap_angle
>= M_PI
/2.0) {
70 // always have at least 2 dots
75 ndots
= 4*int(M_PI
/(2.0*gap_angle
));
76 gap_angle
= (M_PI
*2.0)/ndots
;
79 for (int i
= 0; i
< ndots
; i
++, ang
+= gap_angle
)
80 dot(cent
+ position(cos(ang
), sin(ang
))*rad
, lt
);
83 // recursive function for dash drawing, used by dashed_ellipse
85 void common_output::ellipse_arc(const position
¢
,
86 const position
&z0
, const position
&z1
,
87 const distance
&dim
, const line_type
<
)
89 assert(lt
.type
== line_type::solid
);
90 assert(dim
.x
!= 0 && dim
.y
!= 0);
92 position zml
= (z0
+ z1
) / 2;
93 // apply affine transformation (from ellipse to circle) to compute angle
94 // of new position, then invert transformation to get exact position
95 double psi
= atan2(zml
.y
/ dim
.y
, zml
.x
/ dim
.x
);
96 position zm
= position(dim
.x
* cos(psi
), dim
.y
* sin(psi
));
97 // to approximate the ellipse arc with one or more circle arcs, we
98 // first compute the radius of curvature in zm
99 double a_2
= dim
.x
* dim
.x
;
100 double a_4
= a_2
* a_2
;
101 double b_2
= dim
.y
* dim
.y
;
102 double b_4
= b_2
* b_2
;
103 double e_2
= a_2
- b_2
;
104 double temp
= a_4
* zm
.y
* zm
.y
+ b_4
* zm
.x
* zm
.x
;
105 double rho
= sqrt(temp
/ a_4
/ b_4
* temp
/ a_4
/ b_4
* temp
);
106 // compute center of curvature circle
107 position M
= position(e_2
* zm
.x
/ a_2
* zm
.x
/ a_2
* zm
.x
,
108 -e_2
* zm
.y
/ b_2
* zm
.y
/ b_2
* zm
.y
);
109 // compute distance between circle and ellipse arc at start and end
110 double phi0
= atan2(z0
.y
- M
.y
, z0
.x
- M
.x
);
111 double phi1
= atan2(z1
.y
- M
.y
, z1
.x
- M
.x
);
112 position M0
= position(rho
* cos(phi0
), rho
* sin(phi0
)) + M
;
113 position M1
= position(rho
* cos(phi1
), rho
* sin(phi1
)) + M
;
114 double dist0
= hypot(z0
- M0
) / sqrt(z0
* z0
);
115 double dist1
= hypot(z1
- M1
) / sqrt(z1
* z1
);
116 if (dist0
< eps
&& dist1
< eps
)
117 solid_arc(M
+ cent
, rho
, phi0
, phi1
, lt
);
119 ellipse_arc(cent
, z0
, zm
, dim
, lt
);
120 ellipse_arc(cent
, zm
, z1
, dim
, lt
);
124 // output a dashed ellipse as a series of arcs
126 void common_output::dashed_ellipse(const position
¢
, const distance
&dim
,
129 assert(lt
.type
== line_type::dashed
);
130 double dim_x
= dim
.x
/ 2;
131 double dim_y
= dim
.y
/ 2;
133 slt
.type
= line_type::solid
;
134 double dw
= lt
.dash_width
;
135 // we use an approximation to compute the ellipse length (found in:
136 // Bronstein, Semendjajew, Taschenbuch der Mathematik)
137 double lambda
= (dim
.x
- dim
.y
) / (dim
.x
+ dim
.y
);
138 double le
= M_PI
/ 2 * (dim
.x
+ dim
.y
)
139 * ((64 - 3 * lambda
* lambda
* lambda
* lambda
)
140 / (64 - 16 * lambda
* lambda
));
141 // for symmetry we make nmax a multiple of 8
142 int nmax
= 8 * int(le
/ dw
/ 8 + 0.5);
147 int ndash
= nmax
/ 2;
148 double gapwidth
= (le
- dw
* ndash
) / ndash
;
150 position z
= position(dim_x
, 0);
153 int jmax
= int(10 / lt
.dash_width
);
154 for (int i
= 0; i
<= nmax
; i
++) {
156 position zpre
= zdot
;
157 double ld
= (int(i
/ 2) + 0.5) * dw
+ int((i
+ 1) / 2) * gapwidth
;
160 // find next position for fixed arc length
165 double phi
= j
* 2 * M_PI
/ jmax
;
166 z
= position(dim_x
* cos(phi
), dim_y
* sin(phi
));
167 dl
= hypot(z
- zold
);
170 // interpolate linearly between the last two points,
171 // using the length difference as the scaling factor
172 double delta
= (ld
- lold
) / dl
;
173 zdot
= zold
+ (z
- zold
) * delta
;
174 // compute angle of new position on the affine circle
175 // and use it to get the exact value on the ellipse
176 double psi
= atan2(zdot
.y
/ dim_y
, zdot
.x
/ dim_x
);
177 zdot
= position(dim_x
* cos(psi
), dim_y
* sin(psi
));
178 if ((i
% 2 == 0) && (i
> 1))
179 ellipse_arc(cent
, zpre
, zdot
, dim
/ 2, slt
);
183 // output a dotted ellipse as a series of dots
185 void common_output::dotted_ellipse(const position
¢
, const distance
&dim
,
188 assert(lt
.type
== line_type::dotted
);
189 double dim_x
= dim
.x
/ 2;
190 double dim_y
= dim
.y
/ 2;
192 slt
.type
= line_type::solid
;
193 // we use an approximation to compute the ellipse length (found in:
194 // Bronstein, Semendjajew, Taschenbuch der Mathematik)
195 double lambda
= (dim
.x
- dim
.y
) / (dim
.x
+ dim
.y
);
196 double le
= M_PI
/ 2 * (dim
.x
+ dim
.y
)
197 * ((64 - 3 * lambda
* lambda
* lambda
* lambda
)
198 / (64 - 16 * lambda
* lambda
));
199 // for symmetry we make nmax a multiple of 4
200 int ndots
= 4 * int(le
/ lt
.dash_width
/ 4 + 0.5);
204 position z
= position(dim_x
, 0);
206 int jmax
= int(10 / lt
.dash_width
);
207 for (int i
= 1; i
<= ndots
; i
++) {
210 double ld
= i
* le
/ ndots
;
212 // find next position for fixed arc length
217 double phi
= j
* 2 * M_PI
/ jmax
;
218 z
= position(dim_x
* cos(phi
), dim_y
* sin(phi
));
219 dl
= hypot(z
- zold
);
222 // interpolate linearly between the last two points,
223 // using the length difference as the scaling factor
224 double delta
= (ld
- lold
) / dl
;
225 position zdot
= zold
+ (z
- zold
) * delta
;
226 // compute angle of new position on the affine circle
227 // and use it to get the exact value on the ellipse
228 double psi
= atan2(zdot
.y
/ dim_y
, zdot
.x
/ dim_x
);
229 zdot
= position(dim_x
* cos(psi
), dim_y
* sin(psi
));
230 dot(cent
+ zdot
, slt
);
234 // return non-zero iff we can compute a center
236 int compute_arc_center(const position
&start
, const position
¢
,
237 const position
&end
, position
*result
)
239 // This finds the point along the vector from start to cent that
240 // is equidistant between start and end.
241 distance c
= cent
- start
;
242 distance e
= end
- start
;
246 *result
= start
+ c
*((e
*e
)/(2.0*n
));
250 // output a dashed arc as a series of arcs
252 void common_output::dashed_arc(const position
&start
, const position
¢
,
253 const position
&end
, const line_type
<
)
255 assert(lt
.type
== line_type::dashed
);
257 if (!compute_arc_center(start
, cent
, end
, &c
)) {
258 line(start
, &end
, 1, lt
);
261 distance start_offset
= start
- c
;
262 distance end_offset
= end
- c
;
263 double start_angle
= atan2(start_offset
.y
, start_offset
.x
);
264 double end_angle
= atan2(end_offset
.y
, end_offset
.x
);
265 double rad
= hypot(c
- start
);
266 double dash_angle
= lt
.dash_width
/rad
;
267 double total_angle
= end_angle
- start_angle
;
268 while (total_angle
< 0)
269 total_angle
+= M_PI
+ M_PI
;
270 if (total_angle
<= dash_angle
*2.0) {
271 solid_arc(cent
, rad
, start_angle
, end_angle
, lt
);
274 int ndashes
= int((total_angle
- dash_angle
)/(dash_angle
*2.0) + .5);
275 double dash_and_gap_angle
= (total_angle
- dash_angle
)/ndashes
;
276 for (int i
= 0; i
<= ndashes
; i
++)
277 solid_arc(cent
, rad
, start_angle
+ i
*dash_and_gap_angle
,
278 start_angle
+ i
*dash_and_gap_angle
+ dash_angle
, lt
);
281 // output a dotted arc as a series of dots
283 void common_output::dotted_arc(const position
&start
, const position
¢
,
284 const position
&end
, const line_type
<
)
286 assert(lt
.type
== line_type::dotted
);
288 if (!compute_arc_center(start
, cent
, end
, &c
)) {
289 line(start
, &end
, 1, lt
);
292 distance start_offset
= start
- c
;
293 distance end_offset
= end
- c
;
294 double start_angle
= atan2(start_offset
.y
, start_offset
.x
);
295 double total_angle
= atan2(end_offset
.y
, end_offset
.x
) - start_angle
;
296 while (total_angle
< 0)
297 total_angle
+= M_PI
+ M_PI
;
298 double rad
= hypot(c
- start
);
299 int ndots
= int(total_angle
/(lt
.dash_width
/rad
) + .5);
303 for (int i
= 0; i
<= ndots
; i
++) {
304 double a
= start_angle
+ (total_angle
*i
)/ndots
;
305 dot(cent
+ position(cos(a
), sin(a
))*rad
, lt
);
310 void common_output::solid_arc(const position
¢
, double rad
,
311 double start_angle
, double end_angle
,
315 slt
.type
= line_type::solid
;
316 arc(cent
+ position(cos(start_angle
), sin(start_angle
))*rad
,
318 cent
+ position(cos(end_angle
), sin(end_angle
))*rad
,
323 void common_output::rounded_box(const position
¢
, const distance
&dim
,
324 double rad
, const line_type
<
, double fill
)
327 filled_rounded_box(cent
, dim
, rad
, fill
);
329 case line_type::invisible
:
331 case line_type::dashed
:
332 dashed_rounded_box(cent
, dim
, rad
, lt
);
334 case line_type::dotted
:
335 dotted_rounded_box(cent
, dim
, rad
, lt
);
337 case line_type::solid
:
338 solid_rounded_box(cent
, dim
, rad
, lt
);
346 void common_output::dashed_rounded_box(const position
¢
,
347 const distance
&dim
, double rad
,
351 slt
.type
= line_type::solid
;
353 double hor_length
= dim
.x
+ (M_PI
/2.0 - 2.0)*rad
;
354 int n_hor_dashes
= int(hor_length
/(lt
.dash_width
*2.0) + .5);
355 double hor_gap_width
= (n_hor_dashes
!= 0
356 ? hor_length
/n_hor_dashes
- lt
.dash_width
359 double vert_length
= dim
.y
+ (M_PI
/2.0 - 2.0)*rad
;
360 int n_vert_dashes
= int(vert_length
/(lt
.dash_width
*2.0) + .5);
361 double vert_gap_width
= (n_vert_dashes
!= 0
362 ? vert_length
/n_vert_dashes
- lt
.dash_width
364 // Note that each corner arc has to be split into two for dashing,
365 // because one part is dashed using vert_gap_width, and the other
366 // using hor_gap_width.
367 double offset
= lt
.dash_width
/2.0;
368 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
369 -M_PI
/4.0, 0, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
370 dash_line(cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
),
371 cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
),
372 slt
, lt
.dash_width
, vert_gap_width
, &offset
);
373 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
374 0, M_PI
/4.0, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
376 offset
= lt
.dash_width
/2.0;
377 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
378 M_PI
/4.0, M_PI
/2, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
379 dash_line(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0),
380 cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0),
381 slt
, lt
.dash_width
, hor_gap_width
, &offset
);
382 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
383 M_PI
/2, 3*M_PI
/4.0, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
385 offset
= lt
.dash_width
/2.0;
386 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
387 3.0*M_PI
/4.0, M_PI
, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
388 dash_line(cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
),
389 cent
+ position(-dim
.x
/2.0, -dim
.y
/2.0 + rad
),
390 slt
, lt
.dash_width
, vert_gap_width
, &offset
);
391 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
392 M_PI
, 5.0*M_PI
/4.0, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
394 offset
= lt
.dash_width
/2.0;
395 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
396 5*M_PI
/4.0, 3*M_PI
/2.0, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
397 dash_line(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0),
398 cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0),
399 slt
, lt
.dash_width
, hor_gap_width
, &offset
);
400 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
401 3*M_PI
/2, 7*M_PI
/4, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
404 // Used by dashed_rounded_box.
406 void common_output::dash_arc(const position
¢
, double rad
,
407 double start_angle
, double end_angle
,
409 double dash_width
, double gap_width
,
412 double length
= (end_angle
- start_angle
)*rad
;
415 if (*offsetp
>= dash_width
) {
416 double rem
= dash_width
+ gap_width
- *offsetp
;
417 if (pos
+ rem
> length
) {
418 *offsetp
+= length
- pos
;
427 double rem
= dash_width
- *offsetp
;
428 if (pos
+ rem
> length
) {
429 solid_arc(cent
, rad
, start_angle
+ pos
/rad
, end_angle
, lt
);
430 *offsetp
+= length
- pos
;
434 solid_arc(cent
, rad
, start_angle
+ pos
/rad
,
435 start_angle
+ (pos
+ rem
)/rad
, lt
);
437 *offsetp
= dash_width
;
443 // Used by dashed_rounded_box.
445 void common_output::dash_line(const position
&start
, const position
&end
,
447 double dash_width
, double gap_width
,
450 distance dist
= end
- start
;
451 double length
= hypot(dist
);
456 if (*offsetp
>= dash_width
) {
457 double rem
= dash_width
+ gap_width
- *offsetp
;
458 if (pos
+ rem
> length
) {
459 *offsetp
+= length
- pos
;
468 double rem
= dash_width
- *offsetp
;
469 if (pos
+ rem
> length
) {
470 line(start
+ dist
*(pos
/length
), &end
, 1, lt
);
471 *offsetp
+= length
- pos
;
475 position
p(start
+ dist
*((pos
+ rem
)/length
));
476 line(start
+ dist
*(pos
/length
), &p
, 1, lt
);
478 *offsetp
= dash_width
;
484 void common_output::dotted_rounded_box(const position
¢
,
485 const distance
&dim
, double rad
,
489 slt
.type
= line_type::solid
;
491 double hor_length
= dim
.x
+ (M_PI
/2.0 - 2.0)*rad
;
492 int n_hor_dots
= int(hor_length
/lt
.dash_width
+ .5);
493 double hor_gap_width
= (n_hor_dots
!= 0
494 ? hor_length
/n_hor_dots
497 double vert_length
= dim
.y
+ (M_PI
/2.0 - 2.0)*rad
;
498 int n_vert_dots
= int(vert_length
/lt
.dash_width
+ .5);
499 double vert_gap_width
= (n_vert_dots
!= 0
500 ? vert_length
/n_vert_dots
502 double epsilon
= lt
.dash_width
/(rad
*100.0);
505 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
506 -M_PI
/4.0, 0, slt
, vert_gap_width
, &offset
);
507 dot_line(cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
),
508 cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
),
509 slt
, vert_gap_width
, &offset
);
510 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
511 0, M_PI
/4.0 - epsilon
, slt
, vert_gap_width
, &offset
);
514 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
515 M_PI
/4.0, M_PI
/2, slt
, hor_gap_width
, &offset
);
516 dot_line(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0),
517 cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0),
518 slt
, hor_gap_width
, &offset
);
519 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
520 M_PI
/2, 3*M_PI
/4.0 - epsilon
, slt
, hor_gap_width
, &offset
);
523 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
524 3.0*M_PI
/4.0, M_PI
, slt
, vert_gap_width
, &offset
);
525 dot_line(cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
),
526 cent
+ position(-dim
.x
/2.0, -dim
.y
/2.0 + rad
),
527 slt
, vert_gap_width
, &offset
);
528 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
529 M_PI
, 5.0*M_PI
/4.0 - epsilon
, slt
, vert_gap_width
, &offset
);
532 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
533 5*M_PI
/4.0, 3*M_PI
/2.0, slt
, hor_gap_width
, &offset
);
534 dot_line(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0),
535 cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0),
536 slt
, hor_gap_width
, &offset
);
537 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
538 3*M_PI
/2, 7*M_PI
/4 - epsilon
, slt
, hor_gap_width
, &offset
);
541 // Used by dotted_rounded_box.
543 void common_output::dot_arc(const position
¢
, double rad
,
544 double start_angle
, double end_angle
,
545 const line_type
<
, double gap_width
,
548 double length
= (end_angle
- start_angle
)*rad
;
551 if (*offsetp
== 0.0) {
552 double ang
= start_angle
+ pos
/rad
;
553 dot(cent
+ position(cos(ang
), sin(ang
))*rad
, lt
);
555 double rem
= gap_width
- *offsetp
;
556 if (pos
+ rem
> length
) {
557 *offsetp
+= length
- pos
;
567 // Used by dotted_rounded_box.
569 void common_output::dot_line(const position
&start
, const position
&end
,
570 const line_type
<
, double gap_width
,
573 distance dist
= end
- start
;
574 double length
= hypot(dist
);
580 dot(start
+ dist
*(pos
/length
), lt
);
581 double rem
= gap_width
- *offsetp
;
582 if (pos
+ rem
> length
) {
583 *offsetp
+= length
- pos
;
593 void common_output::solid_rounded_box(const position
¢
,
594 const distance
&dim
, double rad
,
597 position tem
= cent
- dim
/2.0;
598 arc(tem
+ position(0.0, rad
),
599 tem
+ position(rad
, rad
),
600 tem
+ position(rad
, 0.0),
602 tem
= cent
+ position(-dim
.x
/2.0, dim
.y
/2.0);
603 arc(tem
+ position(rad
, 0.0),
604 tem
+ position(rad
, -rad
),
605 tem
+ position(0.0, -rad
),
607 tem
= cent
+ dim
/2.0;
608 arc(tem
+ position(0.0, -rad
),
609 tem
+ position(-rad
, -rad
),
610 tem
+ position(-rad
, 0.0),
612 tem
= cent
+ position(dim
.x
/2.0, -dim
.y
/2.0);
613 arc(tem
+ position(-rad
, 0.0),
614 tem
+ position(-rad
, rad
),
615 tem
+ position(0.0, rad
),
618 end
= cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
);
619 line(cent
- dim
/2.0 + position(0.0, rad
), &end
, 1, lt
);
620 end
= cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0);
621 line(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0), &end
, 1, lt
);
622 end
= cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
);
623 line(cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
), &end
, 1, lt
);
624 end
= cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0);
625 line(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0), &end
, 1, lt
);
628 void common_output::filled_rounded_box(const position
¢
,
629 const distance
&dim
, double rad
,
633 ilt
.type
= line_type::invisible
;
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
);
636 circle(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
, ilt
, fill
);
637 circle(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
, ilt
, fill
);
639 vec
[0] = cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
);
640 vec
[1] = cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
);
641 vec
[2] = cent
+ position(-dim
.x
/2.0, -dim
.y
/2.0 + rad
);
642 vec
[3] = cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
);
643 polygon(vec
, 4, ilt
, fill
);
644 vec
[0] = cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0);
645 vec
[1] = cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0);
646 vec
[2] = cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0);
647 vec
[3] = cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0);
648 polygon(vec
, 4, ilt
, fill
);