Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_dda_line.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry (AGG) - Version 2.5
00003 // A high quality rendering engine for C++
00004 // Copyright (C) 2002-2006 Maxim Shemanarev
00005 // Contact: mcseem@antigrain.com
00006 //          mcseemagg@yahoo.com
00007 //          http://antigrain.com
00008 // 
00009 // AGG is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 // 
00014 // AGG is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU General Public License
00020 // along with AGG; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00022 // MA 02110-1301, USA.
00023 //----------------------------------------------------------------------------
00024 
00025 #ifndef AGG_DDA_LINE_INCLUDED
00026 #define AGG_DDA_LINE_INCLUDED
00027 
00028 #include <stdlib.h>
00029 #include "agg_basics.h"
00030 
00031 namespace agg
00032 {
00033 
00034     //===================================================dda_line_interpolator
00035     template<int FractionShift, int YShift=0> class dda_line_interpolator
00036     {
00037     public:
00038         //--------------------------------------------------------------------
00039         dda_line_interpolator() {}
00040 
00041         //--------------------------------------------------------------------
00042         dda_line_interpolator(int y1, int y2, unsigned count) :
00043             m_y(y1),
00044             m_inc(((y2 - y1) << FractionShift) / int(count)),
00045             m_dy(0)
00046         {
00047         }
00048 
00049         //--------------------------------------------------------------------
00050         void operator ++ ()
00051         {
00052             m_dy += m_inc;
00053         }
00054 
00055         //--------------------------------------------------------------------
00056         void operator -- ()
00057         {
00058             m_dy -= m_inc;
00059         }
00060 
00061         //--------------------------------------------------------------------
00062         void operator += (unsigned n)
00063         {
00064             m_dy += m_inc * n;
00065         }
00066 
00067         //--------------------------------------------------------------------
00068         void operator -= (unsigned n)
00069         {
00070             m_dy -= m_inc * n;
00071         }
00072 
00073 
00074         //--------------------------------------------------------------------
00075         int y()  const { return m_y + (m_dy >> (FractionShift-YShift)); }
00076         int dy() const { return m_dy; }
00077 
00078 
00079     private:
00080         int m_y;
00081         int m_inc;
00082         int m_dy;
00083     };
00084 
00085 
00086 
00087 
00088 
00089     //=================================================dda2_line_interpolator
00090     class dda2_line_interpolator
00091     {
00092     public:
00093         typedef int save_data_type;
00094         enum save_size_e { save_size = 2 };
00095 
00096         //--------------------------------------------------------------------
00097         dda2_line_interpolator() {}
00098 
00099         //-------------------------------------------- Forward-adjusted line
00100         dda2_line_interpolator(int y1, int y2, int count) :
00101             m_cnt(count <= 0 ? 1 : count),
00102             m_lft((y2 - y1) / m_cnt),
00103             m_rem((y2 - y1) % m_cnt),
00104             m_mod(m_rem),
00105             m_y(y1)
00106         {
00107             if(m_mod <= 0)
00108             {
00109                 m_mod += count;
00110                 m_rem += count;
00111                 m_lft--;
00112             }
00113             m_mod -= count;
00114         }
00115 
00116         //-------------------------------------------- Backward-adjusted line
00117         dda2_line_interpolator(int y1, int y2, int count, int) :
00118             m_cnt(count <= 0 ? 1 : count),
00119             m_lft((y2 - y1) / m_cnt),
00120             m_rem((y2 - y1) % m_cnt),
00121             m_mod(m_rem),
00122             m_y(y1)
00123         {
00124             if(m_mod <= 0)
00125             {
00126                 m_mod += count;
00127                 m_rem += count;
00128                 m_lft--;
00129             }
00130         }
00131 
00132         //-------------------------------------------- Backward-adjusted line
00133         dda2_line_interpolator(int y, int count) :
00134             m_cnt(count <= 0 ? 1 : count),
00135             m_lft(y / m_cnt),
00136             m_rem(y % m_cnt),
00137             m_mod(m_rem),
00138             m_y(0)
00139         {
00140             if(m_mod <= 0)
00141             {
00142                 m_mod += count;
00143                 m_rem += count;
00144                 m_lft--;
00145             }
00146         }
00147 
00148 
00149         //--------------------------------------------------------------------
00150         void save(save_data_type* data) const
00151         {
00152             data[0] = m_mod;
00153             data[1] = m_y;
00154         }
00155 
00156         //--------------------------------------------------------------------
00157         void load(const save_data_type* data)
00158         {
00159             m_mod = data[0];
00160             m_y   = data[1];
00161         }
00162 
00163         //--------------------------------------------------------------------
00164         void operator++()
00165         {
00166             m_mod += m_rem;
00167             m_y += m_lft;
00168             if(m_mod > 0)
00169             {
00170                 m_mod -= m_cnt;
00171                 m_y++;
00172             }
00173         }
00174 
00175         //--------------------------------------------------------------------
00176         void operator--()
00177         {
00178             if(m_mod <= m_rem)
00179             {
00180                 m_mod += m_cnt;
00181                 m_y--;
00182             }
00183             m_mod -= m_rem;
00184             m_y -= m_lft;
00185         }
00186 
00187         //--------------------------------------------------------------------
00188         void adjust_forward()
00189         {
00190             m_mod -= m_cnt;
00191         }
00192 
00193         //--------------------------------------------------------------------
00194         void adjust_backward()
00195         {
00196             m_mod += m_cnt;
00197         }
00198 
00199         //--------------------------------------------------------------------
00200         int mod() const { return m_mod; }
00201         int rem() const { return m_rem; }
00202         int lft() const { return m_lft; }
00203 
00204         //--------------------------------------------------------------------
00205         int y() const { return m_y; }
00206 
00207     private:
00208         int m_cnt;
00209         int m_lft;
00210         int m_rem;
00211         int m_mod;
00212         int m_y;
00213     };
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221     //---------------------------------------------line_bresenham_interpolator
00222     class line_bresenham_interpolator
00223     {
00224     public:
00225         enum subpixel_scale_e
00226         {
00227             subpixel_shift = 8,
00228             subpixel_scale = 1 << subpixel_shift,
00229             subpixel_mask  = subpixel_scale - 1
00230         };
00231 
00232         //--------------------------------------------------------------------
00233         static int line_lr(int v) { return v >> subpixel_shift; }
00234 
00235         //--------------------------------------------------------------------
00236         line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
00237             m_x1_lr(line_lr(x1)),
00238             m_y1_lr(line_lr(y1)),
00239             m_x2_lr(line_lr(x2)),
00240             m_y2_lr(line_lr(y2)),
00241             m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
00242             m_len(m_ver ? abs(m_y2_lr - m_y1_lr) : 
00243                           abs(m_x2_lr - m_x1_lr)),
00244             m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
00245             m_interpolator(m_ver ? x1 : y1, 
00246                            m_ver ? x2 : y2, 
00247                            m_len)
00248         {
00249         }
00250     
00251         //--------------------------------------------------------------------
00252         bool     is_ver() const { return m_ver; }
00253         unsigned len()    const { return m_len; }
00254         int      inc()    const { return m_inc; }
00255 
00256         //--------------------------------------------------------------------
00257         void hstep()
00258         {
00259             ++m_interpolator;
00260             m_x1_lr += m_inc;
00261         }
00262 
00263         //--------------------------------------------------------------------
00264         void vstep()
00265         {
00266             ++m_interpolator;
00267             m_y1_lr += m_inc;
00268         }
00269 
00270         //--------------------------------------------------------------------
00271         int x1() const { return m_x1_lr; }
00272         int y1() const { return m_y1_lr; }
00273         int x2() const { return line_lr(m_interpolator.y()); }
00274         int y2() const { return line_lr(m_interpolator.y()); }
00275         int x2_hr() const { return m_interpolator.y(); }
00276         int y2_hr() const { return m_interpolator.y(); }
00277 
00278     private:
00279         int                    m_x1_lr;
00280         int                    m_y1_lr;
00281         int                    m_x2_lr;
00282         int                    m_y2_lr;
00283         bool                   m_ver;
00284         unsigned               m_len;
00285         int                    m_inc;
00286         dda2_line_interpolator m_interpolator;
00287 
00288     };
00289 
00290 
00291 }
00292 
00293 
00294 
00295 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines