Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_span_interpolator_linear.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_SPAN_INTERPOLATOR_LINEAR_INCLUDED
00026 #define AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED
00027 
00028 #include "agg_basics.h"
00029 #include "agg_dda_line.h"
00030 #include "agg_trans_affine.h"
00031 
00032 namespace agg
00033 {
00034 
00035     //================================================span_interpolator_linear
00036     template<class Transformer = trans_affine, unsigned SubpixelShift = 8> 
00037     class span_interpolator_linear
00038     {
00039     public:
00040         typedef Transformer trans_type;
00041 
00042         enum subpixel_scale_e
00043         {
00044             subpixel_shift = SubpixelShift,
00045             subpixel_scale  = 1 << subpixel_shift
00046         };
00047 
00048         //--------------------------------------------------------------------
00049         span_interpolator_linear() {}
00050         span_interpolator_linear(const trans_type& trans) : m_trans(&trans) {}
00051         span_interpolator_linear(const trans_type& trans,
00052                                  double x, double y, unsigned len) :
00053             m_trans(&trans)
00054         {
00055             begin(x, y, len);
00056         }
00057 
00058         //----------------------------------------------------------------
00059         const trans_type& transformer() const { return *m_trans; }
00060         void transformer(const trans_type& trans) { m_trans = &trans; }
00061 
00062         //----------------------------------------------------------------
00063         void begin(double x, double y, unsigned len)
00064         {
00065             double tx;
00066             double ty;
00067 
00068             tx = x;
00069             ty = y;
00070             m_trans->transform(&tx, &ty);
00071             int x1 = iround(tx * subpixel_scale);
00072             int y1 = iround(ty * subpixel_scale);
00073 
00074             tx = x + len;
00075             ty = y;
00076             m_trans->transform(&tx, &ty);
00077             int x2 = iround(tx * subpixel_scale);
00078             int y2 = iround(ty * subpixel_scale);
00079 
00080             m_li_x = dda2_line_interpolator(x1, x2, len);
00081             m_li_y = dda2_line_interpolator(y1, y2, len);
00082         }
00083 
00084         //----------------------------------------------------------------
00085         void resynchronize(double xe, double ye, unsigned len)
00086         {
00087             m_trans->transform(&xe, &ye);
00088             m_li_x = dda2_line_interpolator(m_li_x.y(), iround(xe * subpixel_scale), len);
00089             m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ye * subpixel_scale), len);
00090         }
00091     
00092         //----------------------------------------------------------------
00093         void operator++()
00094         {
00095             ++m_li_x;
00096             ++m_li_y;
00097         }
00098 
00099         //----------------------------------------------------------------
00100         void coordinates(int* x, int* y) const
00101         {
00102             *x = m_li_x.y();
00103             *y = m_li_y.y();
00104         }
00105 
00106     private:
00107         const trans_type* m_trans;
00108         dda2_line_interpolator m_li_x;
00109         dda2_line_interpolator m_li_y;
00110     };
00111 
00112 
00113 
00114 
00115 
00116 
00117     //=====================================span_interpolator_linear_subdiv
00118     template<class Transformer = trans_affine, unsigned SubpixelShift = 8> 
00119     class span_interpolator_linear_subdiv
00120     {
00121     public:
00122         typedef Transformer trans_type;
00123 
00124         enum subpixel_scale_e
00125         {
00126             subpixel_shift = SubpixelShift,
00127             subpixel_scale = 1 << subpixel_shift
00128         };
00129 
00130 
00131         //----------------------------------------------------------------
00132         span_interpolator_linear_subdiv() :
00133             m_subdiv_shift(4),
00134             m_subdiv_size(1 << m_subdiv_shift),
00135             m_subdiv_mask(m_subdiv_size - 1) {}
00136 
00137         span_interpolator_linear_subdiv(const trans_type& trans, 
00138                                         unsigned subdiv_shift = 4) : 
00139             m_subdiv_shift(subdiv_shift),
00140             m_subdiv_size(1 << m_subdiv_shift),
00141             m_subdiv_mask(m_subdiv_size - 1),
00142             m_trans(&trans) {}
00143 
00144         span_interpolator_linear_subdiv(const trans_type& trans,
00145                                         double x, double y, unsigned len,
00146                                         unsigned subdiv_shift = 4) :
00147             m_subdiv_shift(subdiv_shift),
00148             m_subdiv_size(1 << m_subdiv_shift),
00149             m_subdiv_mask(m_subdiv_size - 1),
00150             m_trans(&trans)
00151         {
00152             begin(x, y, len);
00153         }
00154 
00155         //----------------------------------------------------------------
00156         const trans_type& transformer() const { return *m_trans; }
00157         void transformer(const trans_type& trans) { m_trans = &trans; }
00158 
00159         //----------------------------------------------------------------
00160         unsigned subdiv_shift() const { return m_subdiv_shift; }
00161         void subdiv_shift(unsigned shift) 
00162         {
00163             m_subdiv_shift = shift;
00164             m_subdiv_size = 1 << m_subdiv_shift;
00165             m_subdiv_mask = m_subdiv_size - 1;
00166         }
00167 
00168         //----------------------------------------------------------------
00169         void begin(double x, double y, unsigned len)
00170         {
00171             double tx;
00172             double ty;
00173             m_pos   = 1;
00174             m_src_x = iround(x * subpixel_scale) + subpixel_scale;
00175             m_src_y = y;
00176             m_len   = len;
00177 
00178             if(len > m_subdiv_size) len = m_subdiv_size;
00179             tx = x;
00180             ty = y;
00181             m_trans->transform(&tx, &ty);
00182             int x1 = iround(tx * subpixel_scale);
00183             int y1 = iround(ty * subpixel_scale);
00184 
00185             tx = x + len;
00186             ty = y;
00187             m_trans->transform(&tx, &ty);
00188 
00189             m_li_x = dda2_line_interpolator(x1, iround(tx * subpixel_scale), len);
00190             m_li_y = dda2_line_interpolator(y1, iround(ty * subpixel_scale), len);
00191         }
00192 
00193         //----------------------------------------------------------------
00194         void operator++()
00195         {
00196             ++m_li_x;
00197             ++m_li_y;
00198             if(m_pos >= m_subdiv_size)
00199             {
00200                 unsigned len = m_len;
00201                 if(len > m_subdiv_size) len = m_subdiv_size;
00202                 double tx = double(m_src_x) / double(subpixel_scale) + len;
00203                 double ty = m_src_y;
00204                 m_trans->transform(&tx, &ty);
00205                 m_li_x = dda2_line_interpolator(m_li_x.y(), iround(tx * subpixel_scale), len);
00206                 m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ty * subpixel_scale), len);
00207                 m_pos = 0;
00208             }
00209             m_src_x += subpixel_scale;
00210             ++m_pos;
00211             --m_len;
00212         }
00213 
00214         //----------------------------------------------------------------
00215         void coordinates(int* x, int* y) const
00216         {
00217             *x = m_li_x.y();
00218             *y = m_li_y.y();
00219         }
00220 
00221     private:
00222         unsigned m_subdiv_shift;
00223         unsigned m_subdiv_size;
00224         unsigned m_subdiv_mask;
00225         const trans_type* m_trans;
00226         dda2_line_interpolator m_li_x;
00227         dda2_line_interpolator m_li_y;
00228         int      m_src_x;
00229         double   m_src_y;
00230         unsigned m_pos;
00231         unsigned m_len;
00232     };
00233 
00234 
00235 }
00236 
00237 
00238 
00239 #endif
00240 
00241 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines