xref: /haiku/headers/libs/agg/agg_bezier_arc.h (revision 1d9d47fc72028bb71b5f232a877231e59cfe2438)
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
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.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 //          mcseemagg@yahoo.com
13 //          http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 //
16 // Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
17 // 4, 7, 10, or 13 vertices.
18 //
19 //----------------------------------------------------------------------------
20 
21 #ifndef AGG_BEZIER_ARC_INCLUDED
22 #define AGG_BEZIER_ARC_INCLUDED
23 
24 #include "agg_conv_transform.h"
25 
26 namespace agg
27 {
28 
29     //-----------------------------------------------------------------------
30     void arc_to_bezier(double cx, double cy, double rx, double ry,
31                        double start_angle, double sweep_angle,
32                        double* curve);
33 
34 
35     //==============================================================bezier_arc
36     //
37     // See implemantaion agg_bezier_arc.cpp
38     //
39     class bezier_arc
40     {
41     public:
42         //--------------------------------------------------------------------
43         bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {}
44         bezier_arc(double x,  double y,
45                    double rx, double ry,
46                    double start_angle,
47                    double sweep_angle)
48         {
49             init(x, y, rx, ry, start_angle, sweep_angle);
50         }
51 
52         //--------------------------------------------------------------------
53         void init(double x,  double y,
54                   double rx, double ry,
55                   double start_angle,
56                   double sweep_angle);
57 
58         //--------------------------------------------------------------------
59         void rewind(unsigned)
60         {
61             m_vertex = 0;
62         }
63 
64         //--------------------------------------------------------------------
65         unsigned vertex(double* x, double* y)
66         {
67             if(m_vertex >= m_num_vertices) return path_cmd_stop;
68             *x = m_vertices[m_vertex];
69             *y = m_vertices[m_vertex + 1];
70             m_vertex += 2;
71             return (m_vertex == 2) ? path_cmd_move_to : m_cmd;
72         }
73 
74         // Supplemantary functions. num_vertices() actually returns doubled
75         // number of vertices. That is, for 1 vertex it returns 2.
76         //--------------------------------------------------------------------
77         unsigned  num_vertices() const { return m_num_vertices; }
78         const double* vertices() const { return m_vertices;     }
79         double*       vertices()       { return m_vertices;     }
80 
81     private:
82         unsigned m_vertex;
83         unsigned m_num_vertices;
84         double   m_vertices[26];
85         unsigned m_cmd;
86     };
87 
88 
89 
90     //==========================================================bezier_arc_svg
91     // Compute an SVG-style bezier arc.
92     //
93     // Computes an elliptical arc from (x1, y1) to (x2, y2). The size and
94     // orientation of the ellipse are defined by two radii (rx, ry)
95     // and an x-axis-rotation, which indicates how the ellipse as a whole
96     // is rotated relative to the current coordinate system. The center
97     // (cx, cy) of the ellipse is calculated automatically to satisfy the
98     // constraints imposed by the other parameters.
99     // large-arc-flag and sweep-flag contribute to the automatic calculations
100     // and help determine how the arc is drawn.
101     class bezier_arc_svg
102     {
103     public:
104         //--------------------------------------------------------------------
105         bezier_arc_svg() : m_arc(), m_radii_ok(false) {}
106 
107         bezier_arc_svg(double x1, double y1,
108                        double rx, double ry,
109                        double angle,
110                        bool large_arc_flag,
111                        bool sweep_flag,
112                        double x2, double y2) :
113             m_arc(), m_radii_ok(false)
114         {
115             init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2);
116         }
117 
118         //--------------------------------------------------------------------
119         void init(double x1, double y1,
120                   double rx, double ry,
121                   double angle,
122                   bool large_arc_flag,
123                   bool sweep_flag,
124                   double x2, double y2);
125 
126         //--------------------------------------------------------------------
127         bool radii_ok() const { return m_radii_ok; }
128 
129         //--------------------------------------------------------------------
130         void rewind(unsigned)
131         {
132             m_arc.rewind(0);
133         }
134 
135         //--------------------------------------------------------------------
136         unsigned vertex(double* x, double* y)
137         {
138             return m_arc.vertex(x, y);
139         }
140 
141         // Supplemantary functions. num_vertices() actually returns doubled
142         // number of vertices. That is, for 1 vertex it returns 2.
143         //--------------------------------------------------------------------
144         unsigned  num_vertices() const { return m_arc.num_vertices(); }
145         const double* vertices() const { return m_arc.vertices();     }
146         double*       vertices()       { return m_arc.vertices();     }
147 
148     private:
149         bezier_arc m_arc;
150         bool       m_radii_ok;
151     };
152 
153 
154 
155 
156 }
157 
158 
159 #endif
160