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
21namespace 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