1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry (AGG) - Version 2.5
3 // A high quality rendering engine for C++
4 // Copyright (C) 2002-2006 Maxim Shemanarev
5 // Contact: mcseem@antigrain.com
6 //          mcseemagg@yahoo.com
7 //          http://antigrain.com
8 //
9 // AGG is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // AGG is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with AGG; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 // MA 02110-1301, USA.
23 //----------------------------------------------------------------------------
24 
25 #ifndef AGG_DDA_LINE_INCLUDED
26 #define AGG_DDA_LINE_INCLUDED
27 
28 #include <stdlib.h>
29 #include "agg_basics.h"
30 
31 namespace agg
32 {
33 
34     //===================================================dda_line_interpolator
35     template<int FractionShift, int YShift=0> class dda_line_interpolator
36     {
37     public:
38         //--------------------------------------------------------------------
dda_line_interpolator()39         dda_line_interpolator() {}
40 
41         //--------------------------------------------------------------------
dda_line_interpolator(int y1,int y2,unsigned count)42         dda_line_interpolator(int y1, int y2, unsigned count) :
43             m_y(y1),
44             m_inc(((y2 - y1) << FractionShift) / int(count)),
45             m_dy(0)
46         {
47         }
48 
49         //--------------------------------------------------------------------
50         void operator ++ ()
51         {
52             m_dy += m_inc;
53         }
54 
55         //--------------------------------------------------------------------
56         void operator -- ()
57         {
58             m_dy -= m_inc;
59         }
60 
61         //--------------------------------------------------------------------
62         void operator += (unsigned n)
63         {
64             m_dy += m_inc * n;
65         }
66 
67         //--------------------------------------------------------------------
68         void operator -= (unsigned n)
69         {
70             m_dy -= m_inc * n;
71         }
72 
73 
74         //--------------------------------------------------------------------
y()75         int y()  const { return m_y + (m_dy >> (FractionShift-YShift)); }
dy()76         int dy() const { return m_dy; }
77 
78 
79     private:
80         int m_y;
81         int m_inc;
82         int m_dy;
83     };
84 
85 
86 
87 
88 
89     //=================================================dda2_line_interpolator
90     class dda2_line_interpolator
91     {
92     public:
93         typedef int save_data_type;
94         enum save_size_e { save_size = 2 };
95 
96         //--------------------------------------------------------------------
dda2_line_interpolator()97         dda2_line_interpolator() {}
98 
99         //-------------------------------------------- Forward-adjusted line
dda2_line_interpolator(int y1,int y2,int count)100         dda2_line_interpolator(int y1, int y2, int count) :
101             m_cnt(count <= 0 ? 1 : count),
102             m_lft((y2 - y1) / m_cnt),
103             m_rem((y2 - y1) % m_cnt),
104             m_mod(m_rem),
105             m_y(y1)
106         {
107             if(m_mod <= 0)
108             {
109                 m_mod += count;
110                 m_rem += count;
111                 m_lft--;
112             }
113             m_mod -= count;
114         }
115 
116         //-------------------------------------------- Backward-adjusted line
dda2_line_interpolator(int y1,int y2,int count,int)117         dda2_line_interpolator(int y1, int y2, int count, int) :
118             m_cnt(count <= 0 ? 1 : count),
119             m_lft((y2 - y1) / m_cnt),
120             m_rem((y2 - y1) % m_cnt),
121             m_mod(m_rem),
122             m_y(y1)
123         {
124             if(m_mod <= 0)
125             {
126                 m_mod += count;
127                 m_rem += count;
128                 m_lft--;
129             }
130         }
131 
132         //-------------------------------------------- Backward-adjusted line
dda2_line_interpolator(int y,int count)133         dda2_line_interpolator(int y, int count) :
134             m_cnt(count <= 0 ? 1 : count),
135             m_lft(y / m_cnt),
136             m_rem(y % m_cnt),
137             m_mod(m_rem),
138             m_y(0)
139         {
140             if(m_mod <= 0)
141             {
142                 m_mod += count;
143                 m_rem += count;
144                 m_lft--;
145             }
146         }
147 
148 
149         //--------------------------------------------------------------------
save(save_data_type * data)150         void save(save_data_type* data) const
151         {
152             data[0] = m_mod;
153             data[1] = m_y;
154         }
155 
156         //--------------------------------------------------------------------
load(const save_data_type * data)157         void load(const save_data_type* data)
158         {
159             m_mod = data[0];
160             m_y   = data[1];
161         }
162 
163         //--------------------------------------------------------------------
164         void operator++()
165         {
166             m_mod += m_rem;
167             m_y += m_lft;
168             if(m_mod > 0)
169             {
170                 m_mod -= m_cnt;
171                 m_y++;
172             }
173         }
174 
175         //--------------------------------------------------------------------
176         void operator--()
177         {
178             if(m_mod <= m_rem)
179             {
180                 m_mod += m_cnt;
181                 m_y--;
182             }
183             m_mod -= m_rem;
184             m_y -= m_lft;
185         }
186 
187         //--------------------------------------------------------------------
adjust_forward()188         void adjust_forward()
189         {
190             m_mod -= m_cnt;
191         }
192 
193         //--------------------------------------------------------------------
adjust_backward()194         void adjust_backward()
195         {
196             m_mod += m_cnt;
197         }
198 
199         //--------------------------------------------------------------------
mod()200         int mod() const { return m_mod; }
rem()201         int rem() const { return m_rem; }
lft()202         int lft() const { return m_lft; }
203 
204         //--------------------------------------------------------------------
y()205         int y() const { return m_y; }
206 
207     private:
208         int m_cnt;
209         int m_lft;
210         int m_rem;
211         int m_mod;
212         int m_y;
213     };
214 
215 
216 
217 
218 
219 
220 
221     //---------------------------------------------line_bresenham_interpolator
222     class line_bresenham_interpolator
223     {
224     public:
225         enum subpixel_scale_e
226         {
227             subpixel_shift = 8,
228             subpixel_scale = 1 << subpixel_shift,
229             subpixel_mask  = subpixel_scale - 1
230         };
231 
232         //--------------------------------------------------------------------
line_lr(int v)233         static int line_lr(int v) { return v >> subpixel_shift; }
234 
235         //--------------------------------------------------------------------
line_bresenham_interpolator(int x1,int y1,int x2,int y2)236         line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
237             m_x1_lr(line_lr(x1)),
238             m_y1_lr(line_lr(y1)),
239             m_x2_lr(line_lr(x2)),
240             m_y2_lr(line_lr(y2)),
241             m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
242             m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
243                           abs(m_x2_lr - m_x1_lr)),
244             m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
245             m_interpolator(m_ver ? x1 : y1,
246                            m_ver ? x2 : y2,
247                            m_len)
248         {
249         }
250 
251         //--------------------------------------------------------------------
is_ver()252         bool     is_ver() const { return m_ver; }
len()253         unsigned len()    const { return m_len; }
inc()254         int      inc()    const { return m_inc; }
255 
256         //--------------------------------------------------------------------
hstep()257         void hstep()
258         {
259             ++m_interpolator;
260             m_x1_lr += m_inc;
261         }
262 
263         //--------------------------------------------------------------------
vstep()264         void vstep()
265         {
266             ++m_interpolator;
267             m_y1_lr += m_inc;
268         }
269 
270         //--------------------------------------------------------------------
x1()271         int x1() const { return m_x1_lr; }
y1()272         int y1() const { return m_y1_lr; }
x2()273         int x2() const { return line_lr(m_interpolator.y()); }
y2()274         int y2() const { return line_lr(m_interpolator.y()); }
x2_hr()275         int x2_hr() const { return m_interpolator.y(); }
y2_hr()276         int y2_hr() const { return m_interpolator.y(); }
277 
278     private:
279         int                    m_x1_lr;
280         int                    m_y1_lr;
281         int                    m_x2_lr;
282         int                    m_y2_lr;
283         bool                   m_ver;
284         unsigned               m_len;
285         int                    m_inc;
286         dda2_line_interpolator m_interpolator;
287 
288     };
289 
290 
291 }
292 
293 
294 
295 #endif
296