1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.4 3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 //---------------------------------------------------------------------------- 11 // Contact: mcseem@antigrain.com 12 // mcseemagg@yahoo.com 13 // http://www.antigrain.com 14 //---------------------------------------------------------------------------- 15 16 #ifndef AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED 17 #define AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED 18 19 #include "agg_basics.h" 20 #include "agg_dda_line.h" 21 #include "agg_trans_affine.h" 22 23 namespace agg 24 { 25 26 //================================================span_interpolator_linear 27 template<class Transformer = trans_affine, unsigned SubpixelShift = 8> 28 class span_interpolator_linear 29 { 30 public: 31 typedef Transformer trans_type; 32 33 enum subpixel_scale_e 34 { 35 subpixel_shift = SubpixelShift, 36 subpixel_scale = 1 << subpixel_shift 37 }; 38 39 //-------------------------------------------------------------------- 40 span_interpolator_linear() {} 41 span_interpolator_linear(const trans_type& trans) : m_trans(&trans) {} 42 span_interpolator_linear(const trans_type& trans, 43 double x, double y, unsigned len) : 44 m_trans(&trans) 45 { 46 begin(x, y, len); 47 } 48 49 //---------------------------------------------------------------- 50 const trans_type& transformer() const { return *m_trans; } 51 void transformer(const trans_type& trans) { m_trans = &trans; } 52 53 //---------------------------------------------------------------- 54 void begin(double x, double y, unsigned len) 55 { 56 double tx; 57 double ty; 58 59 tx = x; 60 ty = y; 61 m_trans->transform(&tx, &ty); 62 int x1 = iround(tx * subpixel_scale); 63 int y1 = iround(ty * subpixel_scale); 64 65 tx = x + len; 66 ty = y; 67 m_trans->transform(&tx, &ty); 68 int x2 = iround(tx * subpixel_scale); 69 int y2 = iround(ty * subpixel_scale); 70 71 m_li_x = dda2_line_interpolator(x1, x2, len); 72 m_li_y = dda2_line_interpolator(y1, y2, len); 73 } 74 75 //---------------------------------------------------------------- 76 void resynchronize(double xe, double ye, unsigned len) 77 { 78 m_trans->transform(&xe, &ye); 79 m_li_x = dda2_line_interpolator(m_li_x.y(), iround(xe * subpixel_scale), len); 80 m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ye * subpixel_scale), len); 81 } 82 83 //---------------------------------------------------------------- 84 void operator++() 85 { 86 ++m_li_x; 87 ++m_li_y; 88 } 89 90 //---------------------------------------------------------------- 91 void coordinates(int* x, int* y) const 92 { 93 *x = m_li_x.y(); 94 *y = m_li_y.y(); 95 } 96 97 private: 98 const trans_type* m_trans; 99 dda2_line_interpolator m_li_x; 100 dda2_line_interpolator m_li_y; 101 }; 102 103 104 105 106 107 108 //=====================================span_interpolator_linear_subdiv 109 template<class Transformer = trans_affine, unsigned SubpixelShift = 8> 110 class span_interpolator_linear_subdiv 111 { 112 public: 113 typedef Transformer trans_type; 114 115 enum subpixel_scale_e 116 { 117 subpixel_shift = SubpixelShift, 118 subpixel_scale = 1 << subpixel_shift 119 }; 120 121 122 //---------------------------------------------------------------- 123 span_interpolator_linear_subdiv() : 124 m_subdiv_shift(4), 125 m_subdiv_size(1 << m_subdiv_shift), 126 m_subdiv_mask(m_subdiv_size - 1) {} 127 128 span_interpolator_linear_subdiv(const trans_type& trans, 129 unsigned subdiv_shift = 4) : 130 m_subdiv_shift(subdiv_shift), 131 m_subdiv_size(1 << m_subdiv_shift), 132 m_subdiv_mask(m_subdiv_size - 1), 133 m_trans(&trans) {} 134 135 span_interpolator_linear_subdiv(const trans_type& trans, 136 double x, double y, unsigned len, 137 unsigned subdiv_shift = 4) : 138 m_subdiv_shift(subdiv_shift), 139 m_subdiv_size(1 << m_subdiv_shift), 140 m_subdiv_mask(m_subdiv_size - 1), 141 m_trans(&trans) 142 { 143 begin(x, y, len); 144 } 145 146 //---------------------------------------------------------------- 147 const trans_type& transformer() const { return *m_trans; } 148 void transformer(const trans_type& trans) { m_trans = &trans; } 149 150 //---------------------------------------------------------------- 151 unsigned subdiv_shift() const { return m_subdiv_shift; } 152 void subdiv_shift(unsigned shift) 153 { 154 m_subdiv_shift = shift; 155 m_subdiv_size = 1 << m_subdiv_shift; 156 m_subdiv_mask = m_subdiv_size - 1; 157 } 158 159 //---------------------------------------------------------------- 160 void begin(double x, double y, unsigned len) 161 { 162 double tx; 163 double ty; 164 m_pos = 1; 165 m_src_x = iround(x * subpixel_scale) + subpixel_scale; 166 m_src_y = y; 167 m_len = len; 168 169 if(len > m_subdiv_size) len = m_subdiv_size; 170 tx = x; 171 ty = y; 172 m_trans->transform(&tx, &ty); 173 int x1 = iround(tx * subpixel_scale); 174 int y1 = iround(ty * subpixel_scale); 175 176 tx = x + len; 177 ty = y; 178 m_trans->transform(&tx, &ty); 179 180 m_li_x = dda2_line_interpolator(x1, iround(tx * subpixel_scale), len); 181 m_li_y = dda2_line_interpolator(y1, iround(ty * subpixel_scale), len); 182 } 183 184 //---------------------------------------------------------------- 185 void operator++() 186 { 187 ++m_li_x; 188 ++m_li_y; 189 if(m_pos >= m_subdiv_size) 190 { 191 unsigned len = m_len; 192 if(len > m_subdiv_size) len = m_subdiv_size; 193 double tx = double(m_src_x) / double(subpixel_scale) + len; 194 double ty = m_src_y; 195 m_trans->transform(&tx, &ty); 196 m_li_x = dda2_line_interpolator(m_li_x.y(), iround(tx * subpixel_scale), len); 197 m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ty * subpixel_scale), len); 198 m_pos = 0; 199 } 200 m_src_x += subpixel_scale; 201 ++m_pos; 202 --m_len; 203 } 204 205 //---------------------------------------------------------------- 206 void coordinates(int* x, int* y) const 207 { 208 *x = m_li_x.y(); 209 *y = m_li_y.y(); 210 } 211 212 private: 213 unsigned m_subdiv_shift; 214 unsigned m_subdiv_size; 215 unsigned m_subdiv_mask; 216 const trans_type* m_trans; 217 dda2_line_interpolator m_li_x; 218 dda2_line_interpolator m_li_y; 219 int m_src_x; 220 double m_src_y; 221 unsigned m_pos; 222 unsigned m_len; 223 }; 224 225 226 } 227 228 229 230 #endif 231 232 233