xref: /haiku/headers/libs/agg/agg_conv_close_polygon.h (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
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 #ifndef AGG_CONV_CLOSE_POLYGON_INCLUDED
17 #define AGG_CONV_CLOSE_POLYGON_INCLUDED
18 
19 #include "agg_basics.h"
20 
21 namespace agg
22 {
23 
24     //======================================================conv_close_polygon
25     template<class VertexSource> class conv_close_polygon
26     {
27     public:
28         conv_close_polygon(VertexSource& vs) : m_source(&vs) {}
29         void attach(VertexSource& source) { m_source = &source; }
30 
31         void rewind(unsigned path_id);
32         unsigned vertex(double* x, double* y);
33 
34     private:
35         conv_close_polygon(const conv_close_polygon<VertexSource>&);
36         const conv_close_polygon<VertexSource>&
37             operator = (const conv_close_polygon<VertexSource>&);
38 
39         VertexSource* m_source;
40         unsigned      m_cmd[2];
41         double        m_x[2];
42         double        m_y[2];
43         unsigned      m_vertex;
44         bool          m_line_to;
45     };
46 
47 
48 
49     //------------------------------------------------------------------------
50     template<class VertexSource>
51     void conv_close_polygon<VertexSource>::rewind(unsigned path_id)
52     {
53         m_source->rewind(path_id);
54         m_vertex = 2;
55         m_line_to = false;
56     }
57 
58 
59 
60     //------------------------------------------------------------------------
61     template<class VertexSource>
62     unsigned conv_close_polygon<VertexSource>::vertex(double* x, double* y)
63     {
64         unsigned cmd = path_cmd_stop;
65         for(;;)
66         {
67             if(m_vertex < 2)
68             {
69                 *x = m_x[m_vertex];
70                 *y = m_y[m_vertex];
71                 cmd = m_cmd[m_vertex];
72                 ++m_vertex;
73                 break;
74             }
75 
76             cmd = m_source->vertex(x, y);
77 
78             if(is_end_poly(cmd))
79             {
80                 cmd |= path_flags_close;
81                 break;
82             }
83 
84             if(is_stop(cmd))
85             {
86                 if(m_line_to)
87                 {
88                     m_cmd[0]  = path_cmd_end_poly | path_flags_close;
89                     m_cmd[1]  = path_cmd_stop;
90                     m_vertex  = 0;
91                     m_line_to = false;
92                     continue;
93                 }
94                 break;
95             }
96 
97             if(is_move_to(cmd))
98             {
99                 if(m_line_to)
100                 {
101                     m_x[0]    = 0.0;
102                     m_y[0]    = 0.0;
103                     m_cmd[0]  = path_cmd_end_poly | path_flags_close;
104                     m_x[1]    = *x;
105                     m_y[1]    = *y;
106                     m_cmd[1]  = cmd;
107                     m_vertex  = 0;
108                     m_line_to = false;
109                     continue;
110                 }
111                 break;
112             }
113 
114             if(is_vertex(cmd))
115             {
116                 m_line_to = true;
117                 break;
118             }
119         }
120         return cmd;
121     }
122 
123 }
124 
125 #endif
126