~s-cecilio/lomse/master

« back to all changes in this revision

Viewing changes to src/agg/src/agg_vcgen_stroke.cpp

  • Committer: cecilios
  • Date: 2010-11-14 17:47:31 UTC
  • Revision ID: git-v1:1fa3764c8c4d338b95b1a537b1e78271170c0025
latest new code. demo_1 tested on linux and win32

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
// Stroke generator
 
17
//
 
18
//----------------------------------------------------------------------------
 
19
#include <math.h>
 
20
#include "agg_vcgen_stroke.h"
 
21
#include "agg_shorten_path.h"
 
22
 
 
23
namespace agg
 
24
{
 
25
 
 
26
    //------------------------------------------------------------------------
 
27
    vcgen_stroke::vcgen_stroke() :
 
28
        m_stroker(),
 
29
        m_src_vertices(),
 
30
        m_out_vertices(),
 
31
        m_shorten(0.0),
 
32
        m_closed(0),
 
33
        m_status(initial),
 
34
        m_src_vertex(0),
 
35
        m_out_vertex(0)
 
36
    {
 
37
    }
 
38
 
 
39
    //------------------------------------------------------------------------
 
40
    void vcgen_stroke::remove_all()
 
41
    {
 
42
        m_src_vertices.remove_all();
 
43
        m_closed = 0;
 
44
        m_status = initial;
 
45
    }
 
46
 
 
47
 
 
48
    //------------------------------------------------------------------------
 
49
    void vcgen_stroke::add_vertex(double x, double y, unsigned cmd)
 
50
    {
 
51
        m_status = initial;
 
52
        if(is_move_to(cmd))
 
53
        {
 
54
            m_src_vertices.modify_last(vertex_dist(x, y));
 
55
        }
 
56
        else
 
57
        {
 
58
            if(is_vertex(cmd))
 
59
            {
 
60
                m_src_vertices.add(vertex_dist(x, y));
 
61
            }
 
62
            else
 
63
            {
 
64
                m_closed = get_close_flag(cmd);
 
65
            }
 
66
        }
 
67
    }
 
68
 
 
69
    //------------------------------------------------------------------------
 
70
    void vcgen_stroke::rewind(unsigned)
 
71
    {
 
72
        if(m_status == initial)
 
73
        {
 
74
            m_src_vertices.close(m_closed != 0);
 
75
            shorten_path(m_src_vertices, m_shorten, m_closed);
 
76
            if(m_src_vertices.size() < 3) m_closed = 0;
 
77
        }
 
78
        m_status = ready;
 
79
        m_src_vertex = 0;
 
80
        m_out_vertex = 0;
 
81
    }
 
82
 
 
83
 
 
84
    //------------------------------------------------------------------------
 
85
    unsigned vcgen_stroke::vertex(double* x, double* y)
 
86
    {
 
87
        unsigned cmd = path_cmd_line_to;
 
88
        while(!is_stop(cmd))
 
89
        {
 
90
            switch(m_status)
 
91
            {
 
92
            case initial:
 
93
                rewind(0);
 
94
 
 
95
            case ready:
 
96
                if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
 
97
                {
 
98
                    cmd = path_cmd_stop;
 
99
                    break;
 
100
                }
 
101
                m_status = m_closed ? outline1 : cap1;
 
102
                cmd = path_cmd_move_to;
 
103
                m_src_vertex = 0;
 
104
                m_out_vertex = 0;
 
105
                break;
 
106
 
 
107
            case cap1:
 
108
                m_stroker.calc_cap(m_out_vertices,
 
109
                                   m_src_vertices[0], 
 
110
                                   m_src_vertices[1], 
 
111
                                   m_src_vertices[0].dist);
 
112
                m_src_vertex = 1;
 
113
                m_prev_status = outline1;
 
114
                m_status = out_vertices;
 
115
                m_out_vertex = 0;
 
116
                break;
 
117
 
 
118
            case cap2:
 
119
                m_stroker.calc_cap(m_out_vertices,
 
120
                                   m_src_vertices[m_src_vertices.size() - 1], 
 
121
                                   m_src_vertices[m_src_vertices.size() - 2], 
 
122
                                   m_src_vertices[m_src_vertices.size() - 2].dist);
 
123
                m_prev_status = outline2;
 
124
                m_status = out_vertices;
 
125
                m_out_vertex = 0;
 
126
                break;
 
127
 
 
128
            case outline1:
 
129
                if(m_closed)
 
130
                {
 
131
                    if(m_src_vertex >= m_src_vertices.size())
 
132
                    {
 
133
                        m_prev_status = close_first;
 
134
                        m_status = end_poly1;
 
135
                        break;
 
136
                    }
 
137
                }
 
138
                else
 
139
                {
 
140
                    if(m_src_vertex >= m_src_vertices.size() - 1)
 
141
                    {
 
142
                        m_status = cap2;
 
143
                        break;
 
144
                    }
 
145
                }
 
146
                m_stroker.calc_join(m_out_vertices, 
 
147
                                    m_src_vertices.prev(m_src_vertex), 
 
148
                                    m_src_vertices.curr(m_src_vertex), 
 
149
                                    m_src_vertices.next(m_src_vertex), 
 
150
                                    m_src_vertices.prev(m_src_vertex).dist,
 
151
                                    m_src_vertices.curr(m_src_vertex).dist);
 
152
                ++m_src_vertex;
 
153
                m_prev_status = m_status;
 
154
                m_status = out_vertices;
 
155
                m_out_vertex = 0;
 
156
                break;
 
157
 
 
158
            case close_first:
 
159
                m_status = outline2;
 
160
                cmd = path_cmd_move_to;
 
161
 
 
162
            case outline2:
 
163
                if(m_src_vertex <= unsigned(m_closed == 0))
 
164
                {
 
165
                    m_status = end_poly2;
 
166
                    m_prev_status = stop;
 
167
                    break;
 
168
                }
 
169
 
 
170
                --m_src_vertex;
 
171
                m_stroker.calc_join(m_out_vertices,
 
172
                                    m_src_vertices.next(m_src_vertex), 
 
173
                                    m_src_vertices.curr(m_src_vertex), 
 
174
                                    m_src_vertices.prev(m_src_vertex), 
 
175
                                    m_src_vertices.curr(m_src_vertex).dist, 
 
176
                                    m_src_vertices.prev(m_src_vertex).dist);
 
177
 
 
178
                m_prev_status = m_status;
 
179
                m_status = out_vertices;
 
180
                m_out_vertex = 0;
 
181
                break;
 
182
 
 
183
            case out_vertices:
 
184
                if(m_out_vertex >= m_out_vertices.size())
 
185
                {
 
186
                    m_status = m_prev_status;
 
187
                }
 
188
                else
 
189
                {
 
190
                    const point_d& c = m_out_vertices[m_out_vertex++];
 
191
                    *x = c.x;
 
192
                    *y = c.y;
 
193
                    return cmd;
 
194
                }
 
195
                break;
 
196
 
 
197
            case end_poly1:
 
198
                m_status = m_prev_status;
 
199
                return path_cmd_end_poly | path_flags_close | path_flags_ccw;
 
200
 
 
201
            case end_poly2:
 
202
                m_status = m_prev_status;
 
203
                return path_cmd_end_poly | path_flags_close | path_flags_cw;
 
204
 
 
205
            case stop:
 
206
                cmd = path_cmd_stop;
 
207
                break;
 
208
            }
 
209
        }
 
210
        return cmd;
 
211
    }
 
212
 
 
213
}