1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Rounded rectangle vertex generator
18 //----------------------------------------------------------------------------
21 #include "agg_rounded_rect.h"
26 //------------------------------------------------------------------------
27 rounded_rect::rounded_rect(double x1
, double y1
, double x2
, double y2
, double r
) :
28 m_x1(x1
), m_y1(y1
), m_x2(x2
), m_y2(y2
),
29 m_rx1(r
), m_ry1(r
), m_rx2(r
), m_ry2(r
),
30 m_rx3(r
), m_ry3(r
), m_rx4(r
), m_ry4(r
)
32 if(x1
> x2
) { m_x1
= x2
; m_x2
= x1
; }
33 if(y1
> y2
) { m_y1
= y2
; m_y2
= y1
; }
36 //--------------------------------------------------------------------
37 void rounded_rect::rect(double x1
, double y1
, double x2
, double y2
)
43 if(x1
> x2
) { m_x1
= x2
; m_x2
= x1
; }
44 if(y1
> y2
) { m_y1
= y2
; m_y2
= y1
; }
47 //--------------------------------------------------------------------
48 void rounded_rect::radius(double r
)
50 m_rx1
= m_ry1
= m_rx2
= m_ry2
= m_rx3
= m_ry3
= m_rx4
= m_ry4
= r
;
53 //--------------------------------------------------------------------
54 void rounded_rect::radius(double rx
, double ry
)
56 m_rx1
= m_rx2
= m_rx3
= m_rx4
= rx
;
57 m_ry1
= m_ry2
= m_ry3
= m_ry4
= ry
;
60 //--------------------------------------------------------------------
61 void rounded_rect::radius(double rx_bottom
, double ry_bottom
,
62 double rx_top
, double ry_top
)
64 m_rx1
= m_rx2
= rx_bottom
;
65 m_rx3
= m_rx4
= rx_top
;
66 m_ry1
= m_ry2
= ry_bottom
;
67 m_ry3
= m_ry4
= ry_top
;
70 //--------------------------------------------------------------------
71 void rounded_rect::radius(double rx1
, double ry1
, double rx2
, double ry2
,
72 double rx3
, double ry3
, double rx4
, double ry4
)
74 m_rx1
= rx1
; m_ry1
= ry1
; m_rx2
= rx2
; m_ry2
= ry2
;
75 m_rx3
= rx3
; m_ry3
= ry3
; m_rx4
= rx4
; m_ry4
= ry4
;
78 //--------------------------------------------------------------------
79 void rounded_rect::normalize_radius()
81 double dx
= fabs(m_y2
- m_y1
);
82 double dy
= fabs(m_x2
- m_x1
);
86 t
= dx
/ (m_rx1
+ m_rx2
); if(t
< k
) k
= t
;
87 t
= dx
/ (m_rx3
+ m_rx4
); if(t
< k
) k
= t
;
88 t
= dy
/ (m_ry1
+ m_ry2
); if(t
< k
) k
= t
;
89 t
= dy
/ (m_ry3
+ m_ry4
); if(t
< k
) k
= t
;
93 m_rx1
*= k
; m_ry1
*= k
; m_rx2
*= k
; m_ry2
*= k
;
94 m_rx3
*= k
; m_ry3
*= k
; m_rx4
*= k
; m_ry4
*= k
;
98 //--------------------------------------------------------------------
99 void rounded_rect::rewind(unsigned)
104 //--------------------------------------------------------------------
105 unsigned rounded_rect::vertex(double* x
, double* y
)
107 unsigned cmd
= path_cmd_stop
;
111 m_arc
.init(m_x1
+ m_rx1
, m_y1
+ m_ry1
, m_rx1
, m_ry1
,
117 cmd
= m_arc
.vertex(x
, y
);
118 if(is_stop(cmd
)) m_status
++;
122 m_arc
.init(m_x2
- m_rx2
, m_y1
+ m_ry2
, m_rx2
, m_ry2
,
128 cmd
= m_arc
.vertex(x
, y
);
129 if(is_stop(cmd
)) m_status
++;
130 else return path_cmd_line_to
;
133 m_arc
.init(m_x2
- m_rx3
, m_y2
- m_ry3
, m_rx3
, m_ry3
,
139 cmd
= m_arc
.vertex(x
, y
);
140 if(is_stop(cmd
)) m_status
++;
141 else return path_cmd_line_to
;
144 m_arc
.init(m_x1
+ m_rx4
, m_y2
- m_ry4
, m_rx4
, m_ry4
,
150 cmd
= m_arc
.vertex(x
, y
);
151 if(is_stop(cmd
)) m_status
++;
152 else return path_cmd_line_to
;
155 cmd
= (unsigned)path_cmd_end_poly
| (unsigned)path_flags_close
| (unsigned)path_flags_ccw
;