Anti-Grain Geometry - AGG (libagg)
2.5
|
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