xref: /haiku/headers/libs/agg/agg_dda_line.h (revision e39da397f5ff79f2db9f9a3ddf1852b6710578af)
139241fe2SDarkWyrm //----------------------------------------------------------------------------
2*e39da397SStephan Aßmus // Anti-Grain Geometry - Version 2.4
3*e39da397SStephan Aßmus // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
439241fe2SDarkWyrm //
539241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software
639241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies.
739241fe2SDarkWyrm // This software is provided "as is" without express or implied
839241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose.
939241fe2SDarkWyrm //
1039241fe2SDarkWyrm //----------------------------------------------------------------------------
1139241fe2SDarkWyrm // Contact: mcseem@antigrain.com
1239241fe2SDarkWyrm //          mcseemagg@yahoo.com
1339241fe2SDarkWyrm //          http://www.antigrain.com
1439241fe2SDarkWyrm //----------------------------------------------------------------------------
1539241fe2SDarkWyrm //
1639241fe2SDarkWyrm // classes dda_line_interpolator, dda2_line_interpolator
1739241fe2SDarkWyrm //
1839241fe2SDarkWyrm //----------------------------------------------------------------------------
1939241fe2SDarkWyrm 
2039241fe2SDarkWyrm #ifndef AGG_DDA_LINE_INCLUDED
2139241fe2SDarkWyrm #define AGG_DDA_LINE_INCLUDED
2239241fe2SDarkWyrm 
2339241fe2SDarkWyrm #include <stdlib.h>
2439241fe2SDarkWyrm #include "agg_basics.h"
2539241fe2SDarkWyrm 
2639241fe2SDarkWyrm namespace agg
2739241fe2SDarkWyrm {
2839241fe2SDarkWyrm 
2939241fe2SDarkWyrm     //===================================================dda_line_interpolator
3039241fe2SDarkWyrm     template<int FractionShift, int YShift=0> class dda_line_interpolator
3139241fe2SDarkWyrm     {
3239241fe2SDarkWyrm     public:
3339241fe2SDarkWyrm         //--------------------------------------------------------------------
dda_line_interpolator()3439241fe2SDarkWyrm         dda_line_interpolator() {}
3539241fe2SDarkWyrm 
3639241fe2SDarkWyrm         //--------------------------------------------------------------------
dda_line_interpolator(int y1,int y2,unsigned count)3739241fe2SDarkWyrm         dda_line_interpolator(int y1, int y2, unsigned count) :
3839241fe2SDarkWyrm             m_y(y1),
3939241fe2SDarkWyrm             m_inc(((y2 - y1) << FractionShift) / int(count)),
4039241fe2SDarkWyrm             m_dy(0)
4139241fe2SDarkWyrm         {
4239241fe2SDarkWyrm         }
4339241fe2SDarkWyrm 
4439241fe2SDarkWyrm         //--------------------------------------------------------------------
4539241fe2SDarkWyrm         void operator ++ ()
4639241fe2SDarkWyrm         {
4739241fe2SDarkWyrm             m_dy += m_inc;
4839241fe2SDarkWyrm         }
4939241fe2SDarkWyrm 
5039241fe2SDarkWyrm         //--------------------------------------------------------------------
5139241fe2SDarkWyrm         void operator -- ()
5239241fe2SDarkWyrm         {
5339241fe2SDarkWyrm             m_dy -= m_inc;
5439241fe2SDarkWyrm         }
5539241fe2SDarkWyrm 
5639241fe2SDarkWyrm         //--------------------------------------------------------------------
5739241fe2SDarkWyrm         void operator += (unsigned n)
5839241fe2SDarkWyrm         {
5939241fe2SDarkWyrm             m_dy += m_inc * n;
6039241fe2SDarkWyrm         }
6139241fe2SDarkWyrm 
6239241fe2SDarkWyrm         //--------------------------------------------------------------------
6339241fe2SDarkWyrm         void operator -= (unsigned n)
6439241fe2SDarkWyrm         {
6539241fe2SDarkWyrm             m_dy -= m_inc * n;
6639241fe2SDarkWyrm         }
6739241fe2SDarkWyrm 
6839241fe2SDarkWyrm 
6939241fe2SDarkWyrm         //--------------------------------------------------------------------
y()7039241fe2SDarkWyrm         int y()  const { return m_y + (m_dy >> (FractionShift-YShift)); }
dy()7139241fe2SDarkWyrm         int dy() const { return m_dy; }
7239241fe2SDarkWyrm 
7339241fe2SDarkWyrm 
7439241fe2SDarkWyrm     private:
7539241fe2SDarkWyrm         int m_y;
7639241fe2SDarkWyrm         int m_inc;
7739241fe2SDarkWyrm         int m_dy;
7839241fe2SDarkWyrm     };
7939241fe2SDarkWyrm 
8039241fe2SDarkWyrm 
8139241fe2SDarkWyrm 
8239241fe2SDarkWyrm 
8339241fe2SDarkWyrm 
8439241fe2SDarkWyrm     //=================================================dda2_line_interpolator
8539241fe2SDarkWyrm     class dda2_line_interpolator
8639241fe2SDarkWyrm     {
8739241fe2SDarkWyrm     public:
8839241fe2SDarkWyrm         typedef int save_data_type;
89*e39da397SStephan Aßmus         enum save_size_e { save_size = 2 };
9039241fe2SDarkWyrm 
9139241fe2SDarkWyrm         //--------------------------------------------------------------------
dda2_line_interpolator()9239241fe2SDarkWyrm         dda2_line_interpolator() {}
9339241fe2SDarkWyrm 
9439241fe2SDarkWyrm         //-------------------------------------------- Forward-adjusted line
dda2_line_interpolator(int y1,int y2,int count)9539241fe2SDarkWyrm         dda2_line_interpolator(int y1, int y2, int count) :
9639241fe2SDarkWyrm             m_cnt(count <= 0 ? 1 : count),
9739241fe2SDarkWyrm             m_lft((y2 - y1) / m_cnt),
9839241fe2SDarkWyrm             m_rem((y2 - y1) % m_cnt),
9939241fe2SDarkWyrm             m_mod(m_rem),
10039241fe2SDarkWyrm             m_y(y1)
10139241fe2SDarkWyrm         {
10239241fe2SDarkWyrm             if(m_mod <= 0)
10339241fe2SDarkWyrm             {
10439241fe2SDarkWyrm                 m_mod += count;
10539241fe2SDarkWyrm                 m_rem += count;
10639241fe2SDarkWyrm                 m_lft--;
10739241fe2SDarkWyrm             }
10839241fe2SDarkWyrm             m_mod -= count;
10939241fe2SDarkWyrm         }
11039241fe2SDarkWyrm 
11139241fe2SDarkWyrm         //-------------------------------------------- Backward-adjusted line
dda2_line_interpolator(int y1,int y2,int count,int)11239241fe2SDarkWyrm         dda2_line_interpolator(int y1, int y2, int count, int) :
11339241fe2SDarkWyrm             m_cnt(count <= 0 ? 1 : count),
11439241fe2SDarkWyrm             m_lft((y2 - y1) / m_cnt),
11539241fe2SDarkWyrm             m_rem((y2 - y1) % m_cnt),
11639241fe2SDarkWyrm             m_mod(m_rem),
11739241fe2SDarkWyrm             m_y(y1)
11839241fe2SDarkWyrm         {
11939241fe2SDarkWyrm             if(m_mod <= 0)
12039241fe2SDarkWyrm             {
12139241fe2SDarkWyrm                 m_mod += count;
12239241fe2SDarkWyrm                 m_rem += count;
12339241fe2SDarkWyrm                 m_lft--;
12439241fe2SDarkWyrm             }
12539241fe2SDarkWyrm         }
12639241fe2SDarkWyrm 
12739241fe2SDarkWyrm         //-------------------------------------------- Backward-adjusted line
dda2_line_interpolator(int y,int count)12839241fe2SDarkWyrm         dda2_line_interpolator(int y, int count) :
12939241fe2SDarkWyrm             m_cnt(count <= 0 ? 1 : count),
13039241fe2SDarkWyrm             m_lft(y / m_cnt),
13139241fe2SDarkWyrm             m_rem(y % m_cnt),
13239241fe2SDarkWyrm             m_mod(m_rem),
13339241fe2SDarkWyrm             m_y(0)
13439241fe2SDarkWyrm         {
13539241fe2SDarkWyrm             if(m_mod <= 0)
13639241fe2SDarkWyrm             {
13739241fe2SDarkWyrm                 m_mod += count;
13839241fe2SDarkWyrm                 m_rem += count;
13939241fe2SDarkWyrm                 m_lft--;
14039241fe2SDarkWyrm             }
14139241fe2SDarkWyrm         }
14239241fe2SDarkWyrm 
14339241fe2SDarkWyrm 
14439241fe2SDarkWyrm         //--------------------------------------------------------------------
save(save_data_type * data)14539241fe2SDarkWyrm         void save(save_data_type* data) const
14639241fe2SDarkWyrm         {
14739241fe2SDarkWyrm             data[0] = m_mod;
14839241fe2SDarkWyrm             data[1] = m_y;
14939241fe2SDarkWyrm         }
15039241fe2SDarkWyrm 
15139241fe2SDarkWyrm         //--------------------------------------------------------------------
load(const save_data_type * data)15239241fe2SDarkWyrm         void load(const save_data_type* data)
15339241fe2SDarkWyrm         {
15439241fe2SDarkWyrm             m_mod = data[0];
15539241fe2SDarkWyrm             m_y   = data[1];
15639241fe2SDarkWyrm         }
15739241fe2SDarkWyrm 
15839241fe2SDarkWyrm         //--------------------------------------------------------------------
15939241fe2SDarkWyrm         void operator++()
16039241fe2SDarkWyrm         {
16139241fe2SDarkWyrm             m_mod += m_rem;
16239241fe2SDarkWyrm             m_y += m_lft;
16339241fe2SDarkWyrm             if(m_mod > 0)
16439241fe2SDarkWyrm             {
16539241fe2SDarkWyrm                 m_mod -= m_cnt;
16639241fe2SDarkWyrm                 m_y++;
16739241fe2SDarkWyrm             }
16839241fe2SDarkWyrm         }
16939241fe2SDarkWyrm 
17039241fe2SDarkWyrm         //--------------------------------------------------------------------
17139241fe2SDarkWyrm         void operator--()
17239241fe2SDarkWyrm         {
17339241fe2SDarkWyrm             if(m_mod <= m_rem)
17439241fe2SDarkWyrm             {
17539241fe2SDarkWyrm                 m_mod += m_cnt;
17639241fe2SDarkWyrm                 m_y--;
17739241fe2SDarkWyrm             }
17839241fe2SDarkWyrm             m_mod -= m_rem;
17939241fe2SDarkWyrm             m_y -= m_lft;
18039241fe2SDarkWyrm         }
18139241fe2SDarkWyrm 
18239241fe2SDarkWyrm         //--------------------------------------------------------------------
adjust_forward()18339241fe2SDarkWyrm         void adjust_forward()
18439241fe2SDarkWyrm         {
18539241fe2SDarkWyrm             m_mod -= m_cnt;
18639241fe2SDarkWyrm         }
18739241fe2SDarkWyrm 
18839241fe2SDarkWyrm         //--------------------------------------------------------------------
adjust_backward()18939241fe2SDarkWyrm         void adjust_backward()
19039241fe2SDarkWyrm         {
19139241fe2SDarkWyrm             m_mod += m_cnt;
19239241fe2SDarkWyrm         }
19339241fe2SDarkWyrm 
19439241fe2SDarkWyrm         //--------------------------------------------------------------------
mod()19539241fe2SDarkWyrm         int mod() const { return m_mod; }
rem()19639241fe2SDarkWyrm         int rem() const { return m_rem; }
lft()19739241fe2SDarkWyrm         int lft() const { return m_lft; }
19839241fe2SDarkWyrm 
19939241fe2SDarkWyrm         //--------------------------------------------------------------------
y()20039241fe2SDarkWyrm         int y() const { return m_y; }
20139241fe2SDarkWyrm 
20239241fe2SDarkWyrm     private:
20339241fe2SDarkWyrm         int m_cnt;
20439241fe2SDarkWyrm         int m_lft;
20539241fe2SDarkWyrm         int m_rem;
20639241fe2SDarkWyrm         int m_mod;
20739241fe2SDarkWyrm         int m_y;
20839241fe2SDarkWyrm     };
20939241fe2SDarkWyrm 
21039241fe2SDarkWyrm 
21139241fe2SDarkWyrm 
21239241fe2SDarkWyrm 
21339241fe2SDarkWyrm 
21439241fe2SDarkWyrm 
21539241fe2SDarkWyrm 
21639241fe2SDarkWyrm     //---------------------------------------------line_bresenham_interpolator
21739241fe2SDarkWyrm     class line_bresenham_interpolator
21839241fe2SDarkWyrm     {
21939241fe2SDarkWyrm     public:
220*e39da397SStephan Aßmus         enum subpixel_scale_e
22139241fe2SDarkWyrm         {
22239241fe2SDarkWyrm             subpixel_shift = 8,
223*e39da397SStephan Aßmus             subpixel_scale = 1 << subpixel_shift,
224*e39da397SStephan Aßmus             subpixel_mask  = subpixel_scale - 1
22539241fe2SDarkWyrm         };
22639241fe2SDarkWyrm 
22739241fe2SDarkWyrm         //--------------------------------------------------------------------
line_lr(int v)22839241fe2SDarkWyrm         static int line_lr(int v) { return v >> subpixel_shift; }
22939241fe2SDarkWyrm 
23039241fe2SDarkWyrm         //--------------------------------------------------------------------
line_bresenham_interpolator(int x1,int y1,int x2,int y2)23139241fe2SDarkWyrm         line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
23239241fe2SDarkWyrm             m_x1_lr(line_lr(x1)),
23339241fe2SDarkWyrm             m_y1_lr(line_lr(y1)),
23439241fe2SDarkWyrm             m_x2_lr(line_lr(x2)),
23539241fe2SDarkWyrm             m_y2_lr(line_lr(y2)),
23639241fe2SDarkWyrm             m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
23739241fe2SDarkWyrm             m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
23839241fe2SDarkWyrm                           abs(m_x2_lr - m_x1_lr)),
23939241fe2SDarkWyrm             m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
24039241fe2SDarkWyrm             m_interpolator(m_ver ? x1 : y1,
24139241fe2SDarkWyrm                            m_ver ? x2 : y2,
24239241fe2SDarkWyrm                            m_len)
24339241fe2SDarkWyrm         {
24439241fe2SDarkWyrm         }
24539241fe2SDarkWyrm 
24639241fe2SDarkWyrm         //--------------------------------------------------------------------
is_ver()24739241fe2SDarkWyrm         bool     is_ver() const { return m_ver; }
len()24839241fe2SDarkWyrm         unsigned len()    const { return m_len; }
inc()24939241fe2SDarkWyrm         int      inc()    const { return m_inc; }
25039241fe2SDarkWyrm 
25139241fe2SDarkWyrm         //--------------------------------------------------------------------
hstep()25239241fe2SDarkWyrm         void hstep()
25339241fe2SDarkWyrm         {
25439241fe2SDarkWyrm             ++m_interpolator;
25539241fe2SDarkWyrm             m_x1_lr += m_inc;
25639241fe2SDarkWyrm         }
25739241fe2SDarkWyrm 
25839241fe2SDarkWyrm         //--------------------------------------------------------------------
vstep()25939241fe2SDarkWyrm         void vstep()
26039241fe2SDarkWyrm         {
26139241fe2SDarkWyrm             ++m_interpolator;
26239241fe2SDarkWyrm             m_y1_lr += m_inc;
26339241fe2SDarkWyrm         }
26439241fe2SDarkWyrm 
26539241fe2SDarkWyrm         //--------------------------------------------------------------------
x1()26639241fe2SDarkWyrm         int x1() const { return m_x1_lr; }
y1()26739241fe2SDarkWyrm         int y1() const { return m_y1_lr; }
x2()26839241fe2SDarkWyrm         int x2() const { return line_lr(m_interpolator.y()); }
y2()26939241fe2SDarkWyrm         int y2() const { return line_lr(m_interpolator.y()); }
x2_hr()27039241fe2SDarkWyrm         int x2_hr() const { return m_interpolator.y(); }
y2_hr()27139241fe2SDarkWyrm         int y2_hr() const { return m_interpolator.y(); }
27239241fe2SDarkWyrm 
27339241fe2SDarkWyrm     private:
27439241fe2SDarkWyrm         int                    m_x1_lr;
27539241fe2SDarkWyrm         int                    m_y1_lr;
27639241fe2SDarkWyrm         int                    m_x2_lr;
27739241fe2SDarkWyrm         int                    m_y2_lr;
27839241fe2SDarkWyrm         bool                   m_ver;
27939241fe2SDarkWyrm         unsigned               m_len;
28039241fe2SDarkWyrm         int                    m_inc;
28139241fe2SDarkWyrm         dda2_line_interpolator m_interpolator;
28239241fe2SDarkWyrm 
28339241fe2SDarkWyrm     };
28439241fe2SDarkWyrm 
28539241fe2SDarkWyrm 
28639241fe2SDarkWyrm }
28739241fe2SDarkWyrm 
28839241fe2SDarkWyrm 
28939241fe2SDarkWyrm 
29039241fe2SDarkWyrm #endif
291