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// classes dda_line_interpolator, dda2_line_interpolator
17//
18//----------------------------------------------------------------------------
19
20#ifndef AGG_DDA_LINE_INCLUDED
21#define AGG_DDA_LINE_INCLUDED
22
23#include <stdlib.h>
24#include "agg_basics.h"
25
26namespace agg
27{
28
29    //===================================================dda_line_interpolator
30    template<int FractionShift, int YShift=0> class dda_line_interpolator
31    {
32    public:
33        //--------------------------------------------------------------------
34        dda_line_interpolator() {}
35
36        //--------------------------------------------------------------------
37        dda_line_interpolator(int y1, int y2, unsigned count) :
38            m_y(y1),
39            m_inc(((y2 - y1) << FractionShift) / int(count)),
40            m_dy(0)
41        {
42        }
43
44        //--------------------------------------------------------------------
45        void operator ++ ()
46        {
47            m_dy += m_inc;
48        }
49
50        //--------------------------------------------------------------------
51        void operator -- ()
52        {
53            m_dy -= m_inc;
54        }
55
56        //--------------------------------------------------------------------
57        void operator += (unsigned n)
58        {
59            m_dy += m_inc * n;
60        }
61
62        //--------------------------------------------------------------------
63        void operator -= (unsigned n)
64        {
65            m_dy -= m_inc * n;
66        }
67
68
69        //--------------------------------------------------------------------
70        int y()  const { return m_y + (m_dy >> (FractionShift-YShift)); }
71        int dy() const { return m_dy; }
72
73
74    private:
75        int m_y;
76        int m_inc;
77        int m_dy;
78    };
79
80
81
82
83
84    //=================================================dda2_line_interpolator
85    class dda2_line_interpolator
86    {
87    public:
88        typedef int save_data_type;
89        enum save_size_e { save_size = 2 };
90
91        //--------------------------------------------------------------------
92        dda2_line_interpolator() {}
93
94        //-------------------------------------------- Forward-adjusted line
95        dda2_line_interpolator(int y1, int y2, int count) :
96            m_cnt(count <= 0 ? 1 : count),
97            m_lft((y2 - y1) / m_cnt),
98            m_rem((y2 - y1) % m_cnt),
99            m_mod(m_rem),
100            m_y(y1)
101        {
102            if(m_mod <= 0)
103            {
104                m_mod += count;
105                m_rem += count;
106                m_lft--;
107            }
108            m_mod -= count;
109        }
110
111        //-------------------------------------------- Backward-adjusted line
112        dda2_line_interpolator(int y1, int y2, int count, int) :
113            m_cnt(count <= 0 ? 1 : count),
114            m_lft((y2 - y1) / m_cnt),
115            m_rem((y2 - y1) % m_cnt),
116            m_mod(m_rem),
117            m_y(y1)
118        {
119            if(m_mod <= 0)
120            {
121                m_mod += count;
122                m_rem += count;
123                m_lft--;
124            }
125        }
126
127        //-------------------------------------------- Backward-adjusted line
128        dda2_line_interpolator(int y, int count) :
129            m_cnt(count <= 0 ? 1 : count),
130            m_lft(y / m_cnt),
131            m_rem(y % m_cnt),
132            m_mod(m_rem),
133            m_y(0)
134        {
135            if(m_mod <= 0)
136            {
137                m_mod += count;
138                m_rem += count;
139                m_lft--;
140            }
141        }
142
143
144        //--------------------------------------------------------------------
145        void save(save_data_type* data) const
146        {
147            data[0] = m_mod;
148            data[1] = m_y;
149        }
150
151        //--------------------------------------------------------------------
152        void load(const save_data_type* data)
153        {
154            m_mod = data[0];
155            m_y   = data[1];
156        }
157
158        //--------------------------------------------------------------------
159        void operator++()
160        {
161            m_mod += m_rem;
162            m_y += m_lft;
163            if(m_mod > 0)
164            {
165                m_mod -= m_cnt;
166                m_y++;
167            }
168        }
169
170        //--------------------------------------------------------------------
171        void operator--()
172        {
173            if(m_mod <= m_rem)
174            {
175                m_mod += m_cnt;
176                m_y--;
177            }
178            m_mod -= m_rem;
179            m_y -= m_lft;
180        }
181
182        //--------------------------------------------------------------------
183        void adjust_forward()
184        {
185            m_mod -= m_cnt;
186        }
187
188        //--------------------------------------------------------------------
189        void adjust_backward()
190        {
191            m_mod += m_cnt;
192        }
193
194        //--------------------------------------------------------------------
195        int mod() const { return m_mod; }
196        int rem() const { return m_rem; }
197        int lft() const { return m_lft; }
198
199        //--------------------------------------------------------------------
200        int y() const { return m_y; }
201
202    private:
203        int m_cnt;
204        int m_lft;
205        int m_rem;
206        int m_mod;
207        int m_y;
208    };
209
210
211
212
213
214
215
216    //---------------------------------------------line_bresenham_interpolator
217    class line_bresenham_interpolator
218    {
219    public:
220        enum subpixel_scale_e
221        {
222            subpixel_shift = 8,
223            subpixel_scale = 1 << subpixel_shift,
224            subpixel_mask  = subpixel_scale - 1
225        };
226
227        //--------------------------------------------------------------------
228        static int line_lr(int v) { return v >> subpixel_shift; }
229
230        //--------------------------------------------------------------------
231        line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
232            m_x1_lr(line_lr(x1)),
233            m_y1_lr(line_lr(y1)),
234            m_x2_lr(line_lr(x2)),
235            m_y2_lr(line_lr(y2)),
236            m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
237            m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
238                          abs(m_x2_lr - m_x1_lr)),
239            m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
240            m_interpolator(m_ver ? x1 : y1,
241                           m_ver ? x2 : y2,
242                           m_len)
243        {
244        }
245
246        //--------------------------------------------------------------------
247        bool     is_ver() const { return m_ver; }
248        unsigned len()    const { return m_len; }
249        int      inc()    const { return m_inc; }
250
251        //--------------------------------------------------------------------
252        void hstep()
253        {
254            ++m_interpolator;
255            m_x1_lr += m_inc;
256        }
257
258        //--------------------------------------------------------------------
259        void vstep()
260        {
261            ++m_interpolator;
262            m_y1_lr += m_inc;
263        }
264
265        //--------------------------------------------------------------------
266        int x1() const { return m_x1_lr; }
267        int y1() const { return m_y1_lr; }
268        int x2() const { return line_lr(m_interpolator.y()); }
269        int y2() const { return line_lr(m_interpolator.y()); }
270        int x2_hr() const { return m_interpolator.y(); }
271        int y2_hr() const { return m_interpolator.y(); }
272
273    private:
274        int                    m_x1_lr;
275        int                    m_y1_lr;
276        int                    m_x2_lr;
277        int                    m_y2_lr;
278        bool                   m_ver;
279        unsigned               m_len;
280        int                    m_inc;
281        dda2_line_interpolator m_interpolator;
282
283    };
284
285
286}
287
288
289
290#endif
291