2 * Copyright (c) 2014 - 2017 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
4 * Copyright (C) 1989 - 1992, 2003, 2007
5 * Free Software Foundation, Inc.
6 * Written by James Clark (jjc@jclark.com)
8 * This is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2, or (at your option) any later
13 * This is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * You should have received a copy of the GNU General Public License along
19 * with groff; see the file COPYING. If not, write to the Free Software
20 * Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
24 #include "pic-config.h"
29 // output a dashed circle as a series of arcs
31 void common_output::dashed_circle(const position
¢
, double rad
,
34 assert(lt
.type
== line_type::dashed
);
36 slt
.type
= line_type::solid
;
37 double dash_angle
= lt
.dash_width
/rad
;
40 if (dash_angle
>= M_PI
/4.0) {
41 if (dash_angle
< M_PI
/2.0) {
42 gap_angle
= M_PI
/2.0 - dash_angle
;
45 else if (dash_angle
< M_PI
) {
46 gap_angle
= M_PI
- dash_angle
;
50 circle(cent
, rad
, slt
, -1.0);
55 ndashes
= 4*int(ceil(M_PI
/(4.0*dash_angle
)));
56 gap_angle
= (M_PI
*2.0)/ndashes
- dash_angle
;
58 for (int i
= 0; i
< ndashes
; i
++) {
59 double start_angle
= i
*(dash_angle
+gap_angle
) - dash_angle
/2.0;
60 solid_arc(cent
, rad
, start_angle
, start_angle
+ dash_angle
, lt
);
64 // output a dotted circle as a series of dots
66 void common_output::dotted_circle(const position
¢
, double rad
,
69 assert(lt
.type
== line_type::dotted
);
70 double gap_angle
= lt
.dash_width
/rad
;
72 if (gap_angle
>= M_PI
/2.0) {
73 // always have at least 2 dots
78 ndots
= 4*int(M_PI
/(2.0*gap_angle
));
79 gap_angle
= (M_PI
*2.0)/ndots
;
82 for (int i
= 0; i
< ndots
; i
++, ang
+= gap_angle
)
83 dot(cent
+ position(cos(ang
), sin(ang
))*rad
, lt
);
86 // recursive function for dash drawing, used by dashed_ellipse
88 void common_output::ellipse_arc(const position
¢
,
89 const position
&z0
, const position
&z1
,
90 const distance
&dim
, const line_type
<
)
92 assert(lt
.type
== line_type::solid
);
93 assert(dim
.x
!= 0 && dim
.y
!= 0);
95 position zml
= (z0
+ z1
) / 2;
96 // apply affine transformation (from ellipse to circle) to compute angle
97 // of new position, then invert transformation to get exact position
98 double psi
= atan2(zml
.y
/ dim
.y
, zml
.x
/ dim
.x
);
99 position zm
= position(dim
.x
* cos(psi
), dim
.y
* sin(psi
));
100 // to approximate the ellipse arc with one or more circle arcs, we
101 // first compute the radius of curvature in zm
102 double a_2
= dim
.x
* dim
.x
;
103 double a_4
= a_2
* a_2
;
104 double b_2
= dim
.y
* dim
.y
;
105 double b_4
= b_2
* b_2
;
106 double e_2
= a_2
- b_2
;
107 double temp
= a_4
* zm
.y
* zm
.y
+ b_4
* zm
.x
* zm
.x
;
108 double rho
= sqrt(temp
/ a_4
/ b_4
* temp
/ a_4
/ b_4
* temp
);
109 // compute center of curvature circle
110 position M
= position(e_2
* zm
.x
/ a_2
* zm
.x
/ a_2
* zm
.x
,
111 -e_2
* zm
.y
/ b_2
* zm
.y
/ b_2
* zm
.y
);
112 // compute distance between circle and ellipse arc at start and end
113 double phi0
= atan2(z0
.y
- M
.y
, z0
.x
- M
.x
);
114 double phi1
= atan2(z1
.y
- M
.y
, z1
.x
- M
.x
);
115 position M0
= position(rho
* cos(phi0
), rho
* sin(phi0
)) + M
;
116 position M1
= position(rho
* cos(phi1
), rho
* sin(phi1
)) + M
;
117 double dist0
= hypot(z0
- M0
) / sqrt(z0
* z0
);
118 double dist1
= hypot(z1
- M1
) / sqrt(z1
* z1
);
119 if (dist0
< eps
&& dist1
< eps
)
120 solid_arc(M
+ cent
, rho
, phi0
, phi1
, lt
);
122 ellipse_arc(cent
, z0
, zm
, dim
, lt
);
123 ellipse_arc(cent
, zm
, z1
, dim
, lt
);
127 // output a dashed ellipse as a series of arcs
129 void common_output::dashed_ellipse(const position
¢
, const distance
&dim
,
132 assert(lt
.type
== line_type::dashed
);
133 double dim_x
= dim
.x
/ 2;
134 double dim_y
= dim
.y
/ 2;
136 slt
.type
= line_type::solid
;
137 double dw
= lt
.dash_width
;
138 // we use an approximation to compute the ellipse length (found in:
139 // Bronstein, Semendjajew, Taschenbuch der Mathematik)
140 double lambda
= (dim
.x
- dim
.y
) / (dim
.x
+ dim
.y
);
141 double le
= M_PI
/ 2 * (dim
.x
+ dim
.y
)
142 * ((64 - 3 * lambda
* lambda
* lambda
* lambda
)
143 / (64 - 16 * lambda
* lambda
));
144 // for symmetry we make nmax a multiple of 8
145 int nmax
= 8 * int(le
/ dw
/ 8 + 0.5);
150 int ndash
= nmax
/ 2;
151 double gapwidth
= (le
- dw
* ndash
) / ndash
;
153 position z
= position(dim_x
, 0);
156 int jmax
= int(10 / lt
.dash_width
);
157 for (int i
= 0; i
<= nmax
; i
++) {
159 position zpre
= zdot
;
160 double ld
= (int(i
/ 2) + 0.5) * dw
+ int((i
+ 1) / 2) * gapwidth
;
163 // find next position for fixed arc length
168 double phi
= j
* 2 * M_PI
/ jmax
;
169 z
= position(dim_x
* cos(phi
), dim_y
* sin(phi
));
170 dl
= hypot(z
- zold
);
173 // interpolate linearly between the last two points,
174 // using the length difference as the scaling factor
175 double delta
= (ld
- lold
) / dl
;
176 zdot
= zold
+ (z
- zold
) * delta
;
177 // compute angle of new position on the affine circle
178 // and use it to get the exact value on the ellipse
179 double psi
= atan2(zdot
.y
/ dim_y
, zdot
.x
/ dim_x
);
180 zdot
= position(dim_x
* cos(psi
), dim_y
* sin(psi
));
181 if ((i
% 2 == 0) && (i
> 1))
182 ellipse_arc(cent
, zpre
, zdot
, dim
/ 2, slt
);
186 // output a dotted ellipse as a series of dots
188 void common_output::dotted_ellipse(const position
¢
, const distance
&dim
,
191 assert(lt
.type
== line_type::dotted
);
192 double dim_x
= dim
.x
/ 2;
193 double dim_y
= dim
.y
/ 2;
195 slt
.type
= line_type::solid
;
196 // we use an approximation to compute the ellipse length (found in:
197 // Bronstein, Semendjajew, Taschenbuch der Mathematik)
198 double lambda
= (dim
.x
- dim
.y
) / (dim
.x
+ dim
.y
);
199 double le
= M_PI
/ 2 * (dim
.x
+ dim
.y
)
200 * ((64 - 3 * lambda
* lambda
* lambda
* lambda
)
201 / (64 - 16 * lambda
* lambda
));
202 // for symmetry we make nmax a multiple of 4
203 int ndots
= 4 * int(le
/ lt
.dash_width
/ 4 + 0.5);
207 position z
= position(dim_x
, 0);
209 int jmax
= int(10 / lt
.dash_width
);
210 for (int i
= 1; i
<= ndots
; i
++) {
213 double ld
= i
* le
/ ndots
;
215 // find next position for fixed arc length
220 double phi
= j
* 2 * M_PI
/ jmax
;
221 z
= position(dim_x
* cos(phi
), dim_y
* sin(phi
));
222 dl
= hypot(z
- zold
);
225 // interpolate linearly between the last two points,
226 // using the length difference as the scaling factor
227 double delta
= (ld
- lold
) / dl
;
228 position zdot
= zold
+ (z
- zold
) * delta
;
229 // compute angle of new position on the affine circle
230 // and use it to get the exact value on the ellipse
231 double psi
= atan2(zdot
.y
/ dim_y
, zdot
.x
/ dim_x
);
232 zdot
= position(dim_x
* cos(psi
), dim_y
* sin(psi
));
233 dot(cent
+ zdot
, slt
);
237 // return non-zero iff we can compute a center
239 int compute_arc_center(const position
&start
, const position
¢
,
240 const position
&end
, position
*result
)
242 // This finds the point along the vector from start to cent that
243 // is equidistant between start and end.
244 distance c
= cent
- start
;
245 distance e
= end
- start
;
249 *result
= start
+ c
*((e
*e
)/(2.0*n
));
253 // output a dashed arc as a series of arcs
255 void common_output::dashed_arc(const position
&start
, const position
¢
,
256 const position
&end
, const line_type
<
)
258 assert(lt
.type
== line_type::dashed
);
260 if (!compute_arc_center(start
, cent
, end
, &c
)) {
261 line(start
, &end
, 1, lt
);
264 distance start_offset
= start
- c
;
265 distance end_offset
= end
- c
;
266 double start_angle
= atan2(start_offset
.y
, start_offset
.x
);
267 double end_angle
= atan2(end_offset
.y
, end_offset
.x
);
268 double rad
= hypot(c
- start
);
269 double dash_angle
= lt
.dash_width
/rad
;
270 double total_angle
= end_angle
- start_angle
;
271 while (total_angle
< 0)
272 total_angle
+= M_PI
+ M_PI
;
273 if (total_angle
<= dash_angle
*2.0) {
274 solid_arc(cent
, rad
, start_angle
, end_angle
, lt
);
277 int ndashes
= int((total_angle
- dash_angle
)/(dash_angle
*2.0) + .5);
278 double dash_and_gap_angle
= (total_angle
- dash_angle
)/ndashes
;
279 for (int i
= 0; i
<= ndashes
; i
++)
280 solid_arc(cent
, rad
, start_angle
+ i
*dash_and_gap_angle
,
281 start_angle
+ i
*dash_and_gap_angle
+ dash_angle
, lt
);
284 // output a dotted arc as a series of dots
286 void common_output::dotted_arc(const position
&start
, const position
¢
,
287 const position
&end
, const line_type
<
)
289 assert(lt
.type
== line_type::dotted
);
291 if (!compute_arc_center(start
, cent
, end
, &c
)) {
292 line(start
, &end
, 1, lt
);
295 distance start_offset
= start
- c
;
296 distance end_offset
= end
- c
;
297 double start_angle
= atan2(start_offset
.y
, start_offset
.x
);
298 double total_angle
= atan2(end_offset
.y
, end_offset
.x
) - start_angle
;
299 while (total_angle
< 0)
300 total_angle
+= M_PI
+ M_PI
;
301 double rad
= hypot(c
- start
);
302 int ndots
= int(total_angle
/(lt
.dash_width
/rad
) + .5);
306 for (int i
= 0; i
<= ndots
; i
++) {
307 double a
= start_angle
+ (total_angle
*i
)/ndots
;
308 dot(cent
+ position(cos(a
), sin(a
))*rad
, lt
);
313 void common_output::solid_arc(const position
¢
, double rad
,
314 double start_angle
, double end_angle
,
318 slt
.type
= line_type::solid
;
319 arc(cent
+ position(cos(start_angle
), sin(start_angle
))*rad
,
321 cent
+ position(cos(end_angle
), sin(end_angle
))*rad
,
325 void common_output::rounded_box(const position
¢
, const distance
&dim
,
326 double rad
, const line_type
<
,
327 double fill
, char *color_fill
)
329 if (fill
>= 0.0 || color_fill
)
330 filled_rounded_box(cent
, dim
, rad
, fill
);
332 case line_type::invisible
:
334 case line_type::dashed
:
335 dashed_rounded_box(cent
, dim
, rad
, lt
);
337 case line_type::dotted
:
338 dotted_rounded_box(cent
, dim
, rad
, lt
);
340 case line_type::solid
:
341 solid_rounded_box(cent
, dim
, rad
, lt
);
348 void common_output::dashed_rounded_box(const position
¢
,
349 const distance
&dim
, double rad
,
353 slt
.type
= line_type::solid
;
355 double hor_length
= dim
.x
+ (M_PI
/2.0 - 2.0)*rad
;
356 int n_hor_dashes
= int(hor_length
/(lt
.dash_width
*2.0) + .5);
357 double hor_gap_width
= (n_hor_dashes
!= 0
358 ? hor_length
/n_hor_dashes
- lt
.dash_width
361 double vert_length
= dim
.y
+ (M_PI
/2.0 - 2.0)*rad
;
362 int n_vert_dashes
= int(vert_length
/(lt
.dash_width
*2.0) + .5);
363 double vert_gap_width
= (n_vert_dashes
!= 0
364 ? vert_length
/n_vert_dashes
- lt
.dash_width
366 // Note that each corner arc has to be split into two for dashing,
367 // because one part is dashed using vert_gap_width, and the other
368 // using hor_gap_width.
369 double offset
= lt
.dash_width
/2.0;
370 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
371 -M_PI
/4.0, 0, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
372 dash_line(cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
),
373 cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
),
374 slt
, lt
.dash_width
, vert_gap_width
, &offset
);
375 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
376 0, M_PI
/4.0, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
378 offset
= lt
.dash_width
/2.0;
379 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
380 M_PI
/4.0, M_PI
/2, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
381 dash_line(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0),
382 cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0),
383 slt
, lt
.dash_width
, hor_gap_width
, &offset
);
384 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
385 M_PI
/2, 3*M_PI
/4.0, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
387 offset
= lt
.dash_width
/2.0;
388 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
389 3.0*M_PI
/4.0, M_PI
, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
390 dash_line(cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
),
391 cent
+ position(-dim
.x
/2.0, -dim
.y
/2.0 + rad
),
392 slt
, lt
.dash_width
, vert_gap_width
, &offset
);
393 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
394 M_PI
, 5.0*M_PI
/4.0, slt
, lt
.dash_width
, vert_gap_width
, &offset
);
396 offset
= lt
.dash_width
/2.0;
397 dash_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
398 5*M_PI
/4.0, 3*M_PI
/2.0, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
399 dash_line(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0),
400 cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0),
401 slt
, lt
.dash_width
, hor_gap_width
, &offset
);
402 dash_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
403 3*M_PI
/2, 7*M_PI
/4, slt
, lt
.dash_width
, hor_gap_width
, &offset
);
406 // Used by dashed_rounded_box.
408 void common_output::dash_arc(const position
¢
, double rad
,
409 double start_angle
, double end_angle
,
411 double dash_width
, double gap_width
,
414 double length
= (end_angle
- start_angle
)*rad
;
417 if (*offsetp
>= dash_width
) {
418 double rem
= dash_width
+ gap_width
- *offsetp
;
419 if (pos
+ rem
> length
) {
420 *offsetp
+= length
- pos
;
429 double rem
= dash_width
- *offsetp
;
430 if (pos
+ rem
> length
) {
431 solid_arc(cent
, rad
, start_angle
+ pos
/rad
, end_angle
, lt
);
432 *offsetp
+= length
- pos
;
436 solid_arc(cent
, rad
, start_angle
+ pos
/rad
,
437 start_angle
+ (pos
+ rem
)/rad
, lt
);
439 *offsetp
= dash_width
;
445 // Used by dashed_rounded_box.
447 void common_output::dash_line(const position
&start
, const position
&end
,
449 double dash_width
, double gap_width
,
452 distance dist
= end
- start
;
453 double length
= hypot(dist
);
458 if (*offsetp
>= dash_width
) {
459 double rem
= dash_width
+ gap_width
- *offsetp
;
460 if (pos
+ rem
> length
) {
461 *offsetp
+= length
- pos
;
470 double rem
= dash_width
- *offsetp
;
471 if (pos
+ rem
> length
) {
472 line(start
+ dist
*(pos
/length
), &end
, 1, lt
);
473 *offsetp
+= length
- pos
;
477 position
p(start
+ dist
*((pos
+ rem
)/length
));
478 line(start
+ dist
*(pos
/length
), &p
, 1, lt
);
480 *offsetp
= dash_width
;
486 void common_output::dotted_rounded_box(const position
¢
,
487 const distance
&dim
, double rad
,
491 slt
.type
= line_type::solid
;
493 double hor_length
= dim
.x
+ (M_PI
/2.0 - 2.0)*rad
;
494 int n_hor_dots
= int(hor_length
/lt
.dash_width
+ .5);
495 double hor_gap_width
= (n_hor_dots
!= 0
496 ? hor_length
/n_hor_dots
499 double vert_length
= dim
.y
+ (M_PI
/2.0 - 2.0)*rad
;
500 int n_vert_dots
= int(vert_length
/lt
.dash_width
+ .5);
501 double vert_gap_width
= (n_vert_dots
!= 0
502 ? vert_length
/n_vert_dots
504 double epsilon
= lt
.dash_width
/(rad
*100.0);
507 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
508 -M_PI
/4.0, 0, slt
, vert_gap_width
, &offset
);
509 dot_line(cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
),
510 cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
),
511 slt
, vert_gap_width
, &offset
);
512 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
513 0, M_PI
/4.0 - epsilon
, slt
, vert_gap_width
, &offset
);
516 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0 - rad
), rad
,
517 M_PI
/4.0, M_PI
/2, slt
, hor_gap_width
, &offset
);
518 dot_line(cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0),
519 cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0),
520 slt
, hor_gap_width
, &offset
);
521 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
522 M_PI
/2, 3*M_PI
/4.0 - epsilon
, slt
, hor_gap_width
, &offset
);
525 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0 - rad
), rad
,
526 3.0*M_PI
/4.0, M_PI
, slt
, vert_gap_width
, &offset
);
527 dot_line(cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
),
528 cent
+ position(-dim
.x
/2.0, -dim
.y
/2.0 + rad
),
529 slt
, vert_gap_width
, &offset
);
530 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
531 M_PI
, 5.0*M_PI
/4.0 - epsilon
, slt
, vert_gap_width
, &offset
);
534 dot_arc(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
,
535 5*M_PI
/4.0, 3*M_PI
/2.0, slt
, hor_gap_width
, &offset
);
536 dot_line(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0),
537 cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0),
538 slt
, hor_gap_width
, &offset
);
539 dot_arc(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
,
540 3*M_PI
/2, 7*M_PI
/4 - epsilon
, slt
, hor_gap_width
, &offset
);
543 // Used by dotted_rounded_box.
545 void common_output::dot_arc(const position
¢
, double rad
,
546 double start_angle
, double end_angle
,
547 const line_type
<
, double gap_width
,
550 double length
= (end_angle
- start_angle
)*rad
;
553 if (*offsetp
== 0.0) {
554 double ang
= start_angle
+ pos
/rad
;
555 dot(cent
+ position(cos(ang
), sin(ang
))*rad
, lt
);
557 double rem
= gap_width
- *offsetp
;
558 if (pos
+ rem
> length
) {
559 *offsetp
+= length
- pos
;
569 // Used by dotted_rounded_box.
571 void common_output::dot_line(const position
&start
, const position
&end
,
572 const line_type
<
, double gap_width
,
575 distance dist
= end
- start
;
576 double length
= hypot(dist
);
582 dot(start
+ dist
*(pos
/length
), lt
);
583 double rem
= gap_width
- *offsetp
;
584 if (pos
+ rem
> length
) {
585 *offsetp
+= length
- pos
;
595 void common_output::solid_rounded_box(const position
¢
,
596 const distance
&dim
, double rad
,
599 position tem
= cent
- dim
/2.0;
600 arc(tem
+ position(0.0, rad
),
601 tem
+ position(rad
, rad
),
602 tem
+ position(rad
, 0.0),
604 tem
= cent
+ position(-dim
.x
/2.0, dim
.y
/2.0);
605 arc(tem
+ position(rad
, 0.0),
606 tem
+ position(rad
, -rad
),
607 tem
+ position(0.0, -rad
),
609 tem
= cent
+ dim
/2.0;
610 arc(tem
+ position(0.0, -rad
),
611 tem
+ position(-rad
, -rad
),
612 tem
+ position(-rad
, 0.0),
614 tem
= cent
+ position(dim
.x
/2.0, -dim
.y
/2.0);
615 arc(tem
+ position(-rad
, 0.0),
616 tem
+ position(-rad
, rad
),
617 tem
+ position(0.0, rad
),
620 end
= cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
);
621 line(cent
- dim
/2.0 + position(0.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
);
624 end
= cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
);
625 line(cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
), &end
, 1, lt
);
626 end
= cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0);
627 line(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0), &end
, 1, lt
);
630 void common_output::filled_rounded_box(const position
¢
,
631 const distance
&dim
, double rad
,
635 ilt
.type
= line_type::invisible
;
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
);
638 circle(cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0 + rad
), rad
, ilt
, fill
);
639 circle(cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0 + rad
), rad
, ilt
, fill
);
641 vec
[0] = cent
+ position(dim
.x
/2.0, dim
.y
/2.0 - rad
);
642 vec
[1] = cent
+ position(-dim
.x
/2.0, dim
.y
/2.0 - rad
);
643 vec
[2] = cent
+ position(-dim
.x
/2.0, -dim
.y
/2.0 + rad
);
644 vec
[3] = cent
+ position(dim
.x
/2.0, -dim
.y
/2.0 + rad
);
645 polygon(vec
, 4, ilt
, fill
);
646 vec
[0] = cent
+ position(dim
.x
/2.0 - rad
, dim
.y
/2.0);
647 vec
[1] = cent
+ position(-dim
.x
/2.0 + rad
, dim
.y
/2.0);
648 vec
[2] = cent
+ position(-dim
.x
/2.0 + rad
, -dim
.y
/2.0);
649 vec
[3] = cent
+ position(dim
.x
/2.0 - rad
, -dim
.y
/2.0);
650 polygon(vec
, 4, ilt
, fill
);