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_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