1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//----------------------------------------------------------------------------
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Anti-Grain Geometry - Version 2.3
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Permission to copy, use, modify, sell and distribute this software
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// is granted provided this copyright notice appears in all copies.
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This software is provided "as is" without express or implied
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// warranty, and with no claim as to its suitability for any purpose.
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//----------------------------------------------------------------------------
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Contact: mcseem@antigrain.com
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//          mcseemagg@yahoo.com
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//          http://www.antigrain.com
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//----------------------------------------------------------------------------
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "agg_basics.h"
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovnamespace agg
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct null_markers : public CFX_Object {
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void remove_all() {}
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void add_vertex(FX_FLOAT, FX_FLOAT, unsigned) {}
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void prepare_src() {}
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void rewind(unsigned) {}
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned vertex(FX_FLOAT*, FX_FLOAT*)
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return path_cmd_stop;
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtemplate<class VertexSource,
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         class Generator,
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         class Markers = null_markers> class conv_adaptor_vcgen : public CFX_Object
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    enum status {
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        initial,
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        accumulate,
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        generate
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    };
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    conv_adaptor_vcgen(VertexSource& source) :
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_source(&source),
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_status(initial)
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {}
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void set_source(VertexSource& source)
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_source = &source;
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Generator& generator()
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_generator;
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const Generator& generator() const
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_generator;
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Markers& markers()
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_markers;
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const Markers& markers() const
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_markers;
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void rewind(unsigned path_id)
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_source->rewind(path_id);
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_status = initial;
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned vertex(FX_FLOAT* x, FX_FLOAT* y);
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovprivate:
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const conv_adaptor_vcgen<VertexSource, Generator, Markers>&
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    VertexSource* m_source;
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Generator     m_generator;
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Markers       m_markers;
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    status        m_status;
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned      m_last_cmd;
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT        m_start_x;
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT        m_start_y;
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtemplate<class VertexSource, class Generator, class Markers>
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovunsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(FX_FLOAT* x, FX_FLOAT* y)
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned cmd = path_cmd_stop;
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bool done = false;
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while(!done) {
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        switch(m_status) {
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case initial:
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_markers.remove_all();
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_status = accumulate;
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case accumulate:
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if(is_stop(m_last_cmd)) {
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return path_cmd_stop;
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_generator.remove_all();
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for(;;) {
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    cmd = m_source->vertex(x, y);
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if(is_vertex(cmd)) {
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        m_last_cmd = cmd;
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if(is_move_to(cmd)) {
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            m_start_x = *x;
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            m_start_y = *y;
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            break;
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        m_generator.add_vertex(*x, *y, cmd);
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        m_markers.add_vertex(*x, *y, path_cmd_line_to);
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if(is_stop(cmd)) {
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            m_last_cmd = path_cmd_stop;
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            break;
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if(is_end_poly(cmd)) {
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            m_generator.add_vertex(*x, *y, cmd);
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            break;
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_generator.rewind(0);
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_status = generate;
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case generate:
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmd = m_generator.vertex(x, y);
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if(is_stop(cmd)) {
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_status = accumulate;
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                done = true;
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return cmd;
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
139