summaryrefslogtreecommitdiff
path: root/core/src/fxge/agg/agg23/agg_curves.h
blob: 495f7a6a8f40b0df24b2b26545a8cba655f256a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// Copyright (C) 2005 Tony Juricic (tonygeek@yahoo.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
//          mcseemagg@yahoo.com
//          http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CURVES_INCLUDED
#define AGG_CURVES_INCLUDED
#include "agg_array.h"
namespace agg
{
struct curve4_points  {
    FX_FLOAT cp[8];
    curve4_points() {}
    curve4_points(FX_FLOAT x1, FX_FLOAT y1,
                  FX_FLOAT x2, FX_FLOAT y2,
                  FX_FLOAT x3, FX_FLOAT y3,
                  FX_FLOAT x4, FX_FLOAT y4)
    {
        cp[0] = x1;
        cp[1] = y1;
        cp[2] = x2;
        cp[3] = y2;
        cp[4] = x3;
        cp[5] = y3;
        cp[6] = x4;
        cp[7] = y4;
    }
    void init(FX_FLOAT x1, FX_FLOAT y1,
              FX_FLOAT x2, FX_FLOAT y2,
              FX_FLOAT x3, FX_FLOAT y3,
              FX_FLOAT x4, FX_FLOAT y4)
    {
        cp[0] = x1;
        cp[1] = y1;
        cp[2] = x2;
        cp[3] = y2;
        cp[4] = x3;
        cp[5] = y3;
        cp[6] = x4;
        cp[7] = y4;
    }
    FX_FLOAT  operator [] (unsigned i) const
    {
        return cp[i];
    }
    FX_FLOAT& operator [] (unsigned i)
    {
        return cp[i];
    }
};
class curve4_div 
{
public:
    curve4_div() :
        m_count(0)
    {}
    curve4_div(FX_FLOAT x1, FX_FLOAT y1,
               FX_FLOAT x2, FX_FLOAT y2,
               FX_FLOAT x3, FX_FLOAT y3,
               FX_FLOAT x4, FX_FLOAT y4) :
        m_count(0)
    {
        init(x1, y1, x2, y2, x3, y3, x4, y4);
    }
    curve4_div(const curve4_points& cp) :
        m_count(0)
    {
        init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
    }
    void reset()
    {
        m_points.remove_all();
        m_count = 0;
    }
    void init(FX_FLOAT x1, FX_FLOAT y1,
              FX_FLOAT x2, FX_FLOAT y2,
              FX_FLOAT x3, FX_FLOAT y3,
              FX_FLOAT x4, FX_FLOAT y4);
    void init(const curve4_points& cp)
    {
        init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
    }
    void rewind(unsigned)
    {
        m_count = 0;
    }
    unsigned vertex(FX_FLOAT* x, FX_FLOAT* y)
    {
        if(m_count >= m_points.size()) {
            return path_cmd_stop;
        }
        const point_type& p = m_points[m_count++];
        *x = p.x;
        *y = p.y;
        return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
    }
    unsigned vertex_flag(FX_FLOAT* x, FX_FLOAT* y, int& flag)
    {
        if(m_count >= m_points.size()) {
            return path_cmd_stop;
        }
        const point_type& p = m_points[m_count++];
        *x = p.x;
        *y = p.y;
        flag = p.flag;
        return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
    }
    int count()
    {
        return m_points.size();
    }
private:
    void bezier(FX_FLOAT x1, FX_FLOAT y1,
                FX_FLOAT x2, FX_FLOAT y2,
                FX_FLOAT x3, FX_FLOAT y3,
                FX_FLOAT x4, FX_FLOAT y4);
    void recursive_bezier(FX_FLOAT x1, FX_FLOAT y1,
                          FX_FLOAT x2, FX_FLOAT y2,
                          FX_FLOAT x3, FX_FLOAT y3,
                          FX_FLOAT x4, FX_FLOAT y4,
                          unsigned level);
    FX_FLOAT    m_distance_tolerance_square;
    FX_FLOAT    m_distance_tolerance_manhattan;
    unsigned              m_count;
    pod_deque<point_type> m_points;
};
class curve4 
{
public:
    curve4() {}
    curve4(FX_FLOAT x1, FX_FLOAT y1,
           FX_FLOAT x2, FX_FLOAT y2,
           FX_FLOAT x3, FX_FLOAT y3,
           FX_FLOAT x4, FX_FLOAT y4)
    {
        init(x1, y1, x2, y2, x3, y3, x4, y4);
    }
    curve4(const curve4_points& cp)
    {
        init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
    }
    void reset()
    {
        m_curve_div.reset();
    }
    void init(FX_FLOAT x1, FX_FLOAT y1,
              FX_FLOAT x2, FX_FLOAT y2,
              FX_FLOAT x3, FX_FLOAT y3,
              FX_FLOAT x4, FX_FLOAT y4)
    {
        m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4);
    }
    void init(const curve4_points& cp)
    {
        init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
    }
    void rewind(unsigned path_id)
    {
        m_curve_div.rewind(path_id);
    }
    unsigned vertex(FX_FLOAT* x, FX_FLOAT* y)
    {
        return m_curve_div.vertex(x, y);
    }
    unsigned vertex_curve_flag(FX_FLOAT* x, FX_FLOAT* y, int& flag)
    {
        return m_curve_div.vertex_flag(x, y, flag);
    }
    int count()
    {
        return m_curve_div.count();
    }
private:
    curve4_div m_curve_div;
};
}
#endif