~ubuntu-branches/ubuntu/lucid/agg/lucid-proposed

« back to all changes in this revision

Viewing changes to src/agg_vcgen_contour.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Rene Engelhard
  • Date: 2005-11-29 02:02:41 UTC
  • Revision ID: james.westby@ubuntu.com-20051129020241-pmlxls0x6j2qv3nm
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//----------------------------------------------------------------------------
 
2
// Anti-Grain Geometry - Version 2.3
 
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
// Contour generator
 
17
//
 
18
//----------------------------------------------------------------------------
 
19
 
 
20
#include <math.h>
 
21
#include "agg_vcgen_contour.h"
 
22
 
 
23
namespace agg
 
24
{
 
25
 
 
26
    //------------------------------------------------------------------------
 
27
    vcgen_contour::vcgen_contour() :
 
28
        m_src_vertices(),
 
29
        m_out_vertices(),
 
30
        m_width(1.0),
 
31
        m_line_join(bevel_join),
 
32
        m_inner_join(inner_miter),
 
33
        m_approx_scale(1.0),
 
34
        m_abs_width(1.0),
 
35
        m_signed_width(1.0),
 
36
        m_miter_limit(4.0),
 
37
        m_inner_miter_limit(1.0 + 1.0/64.0),
 
38
        m_status(initial),
 
39
        m_src_vertex(0),
 
40
        m_closed(0),
 
41
        m_orientation(0),
 
42
        m_auto_detect(false)
 
43
    {
 
44
    }
 
45
 
 
46
 
 
47
    //------------------------------------------------------------------------
 
48
    void vcgen_contour::remove_all()
 
49
    {
 
50
        m_src_vertices.remove_all();
 
51
        m_closed = 0;
 
52
        m_orientation = 0;
 
53
        m_abs_width = fabs(m_width);
 
54
        m_signed_width = m_width;
 
55
        m_status = initial;
 
56
    }
 
57
 
 
58
 
 
59
    //------------------------------------------------------------------------
 
60
    void vcgen_contour::miter_limit_theta(double t)
 
61
    { 
 
62
        m_miter_limit = 1.0 / sin(t * 0.5) ;
 
63
    }
 
64
 
 
65
 
 
66
    //------------------------------------------------------------------------
 
67
    void vcgen_contour::add_vertex(double x, double y, unsigned cmd)
 
68
    {
 
69
        m_status = initial;
 
70
        if(is_move_to(cmd))
 
71
        {
 
72
            m_src_vertices.modify_last(vertex_dist(x, y));
 
73
        }
 
74
        else
 
75
        {
 
76
            if(is_vertex(cmd))
 
77
            {
 
78
                m_src_vertices.add(vertex_dist(x, y));
 
79
            }
 
80
            else
 
81
            {
 
82
                if(is_end_poly(cmd))
 
83
                {
 
84
                    m_closed = get_close_flag(cmd);
 
85
                    if(m_orientation == path_flags_none) 
 
86
                    {
 
87
                        m_orientation = get_orientation(cmd);
 
88
                    }
 
89
                }
 
90
            }
 
91
        }
 
92
    }
 
93
 
 
94
 
 
95
    //------------------------------------------------------------------------
 
96
    void vcgen_contour::rewind(unsigned)
 
97
    {
 
98
        if(m_status == initial)
 
99
        {
 
100
            m_src_vertices.close(true);
 
101
            m_signed_width = m_width;
 
102
            if(m_auto_detect)
 
103
            {
 
104
                if(!is_oriented(m_orientation))
 
105
                {
 
106
                    m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ? 
 
107
                                    path_flags_ccw : 
 
108
                                    path_flags_cw;
 
109
                }
 
110
            }
 
111
            if(is_oriented(m_orientation))
 
112
            {
 
113
                m_signed_width = is_ccw(m_orientation) ? m_width : -m_width;
 
114
            }
 
115
        }
 
116
        m_status = ready;
 
117
        m_src_vertex = 0;
 
118
    }
 
119
 
 
120
 
 
121
    //------------------------------------------------------------------------
 
122
    unsigned vcgen_contour::vertex(double* x, double* y)
 
123
    {
 
124
        unsigned cmd = path_cmd_line_to;
 
125
        while(!is_stop(cmd))
 
126
        {
 
127
            switch(m_status)
 
128
            {
 
129
            case initial:
 
130
                rewind(0);
 
131
 
 
132
            case ready:
 
133
                if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
 
134
                {
 
135
                    cmd = path_cmd_stop;
 
136
                    break;
 
137
                }
 
138
                m_status = outline;
 
139
                cmd = path_cmd_move_to;
 
140
                m_src_vertex = 0;
 
141
                m_out_vertex = 0;
 
142
 
 
143
            case outline:
 
144
                if(m_src_vertex >= m_src_vertices.size())
 
145
                {
 
146
                    m_status = end_poly;
 
147
                    break;
 
148
                }
 
149
                stroke_calc_join(m_out_vertices, 
 
150
                                 m_src_vertices.prev(m_src_vertex), 
 
151
                                 m_src_vertices.curr(m_src_vertex), 
 
152
                                 m_src_vertices.next(m_src_vertex), 
 
153
                                 m_src_vertices.prev(m_src_vertex).dist,
 
154
                                 m_src_vertices.curr(m_src_vertex).dist,
 
155
                                 m_signed_width, 
 
156
                                 m_line_join,
 
157
                                 m_inner_join,
 
158
                                 m_miter_limit,
 
159
                                 m_inner_miter_limit,
 
160
                                 m_approx_scale);
 
161
                ++m_src_vertex;
 
162
                m_status = out_vertices;
 
163
                m_out_vertex = 0;
 
164
 
 
165
            case out_vertices:
 
166
                if(m_out_vertex >= m_out_vertices.size())
 
167
                {
 
168
                    m_status = outline;
 
169
                }
 
170
                else
 
171
                {
 
172
                    const point_type& c = m_out_vertices[m_out_vertex++];
 
173
                    *x = c.x;
 
174
                    *y = c.y;
 
175
                    return cmd;
 
176
                }
 
177
                break;
 
178
 
 
179
            case end_poly:
 
180
                if(!m_closed) return path_cmd_stop;
 
181
                m_status = stop;
 
182
                return path_cmd_end_poly | path_flags_close | path_flags_ccw;
 
183
 
 
184
            case stop:
 
185
                return path_cmd_stop;
 
186
            }
 
187
        }
 
188
        return cmd;
 
189
    }
 
190
 
 
191
}