1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry (AGG) - Version 2.5 3 // A high quality rendering engine for C++ 4 // Copyright (C) 2002-2006 Maxim Shemanarev 5 // Contact: mcseem@antigrain.com 6 // mcseemagg@yahoo.com 7 // http://antigrain.com 8 // 9 // AGG is free software; you can redistribute it and/or 10 // modify it under the terms of the GNU General Public License 11 // as published by the Free Software Foundation; either version 2 12 // of the License, or (at your option) any later version. 13 // 14 // AGG is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with AGG; if not, write to the Free Software 21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 22 // MA 02110-1301, USA. 23 //---------------------------------------------------------------------------- 24 25 #ifndef AGG_DDA_LINE_INCLUDED 26 #define AGG_DDA_LINE_INCLUDED 27 28 #include <stdlib.h> 29 #include "agg_basics.h" 30 31 namespace agg 32 { 33 34 //===================================================dda_line_interpolator 35 template<int FractionShift, int YShift=0> class dda_line_interpolator 36 { 37 public: 38 //-------------------------------------------------------------------- dda_line_interpolator()39 dda_line_interpolator() {} 40 41 //-------------------------------------------------------------------- dda_line_interpolator(int y1,int y2,unsigned count)42 dda_line_interpolator(int y1, int y2, unsigned count) : 43 m_y(y1), 44 m_inc(((y2 - y1) << FractionShift) / int(count)), 45 m_dy(0) 46 { 47 } 48 49 //-------------------------------------------------------------------- 50 void operator ++ () 51 { 52 m_dy += m_inc; 53 } 54 55 //-------------------------------------------------------------------- 56 void operator -- () 57 { 58 m_dy -= m_inc; 59 } 60 61 //-------------------------------------------------------------------- 62 void operator += (unsigned n) 63 { 64 m_dy += m_inc * n; 65 } 66 67 //-------------------------------------------------------------------- 68 void operator -= (unsigned n) 69 { 70 m_dy -= m_inc * n; 71 } 72 73 74 //-------------------------------------------------------------------- y()75 int y() const { return m_y + (m_dy >> (FractionShift-YShift)); } dy()76 int dy() const { return m_dy; } 77 78 79 private: 80 int m_y; 81 int m_inc; 82 int m_dy; 83 }; 84 85 86 87 88 89 //=================================================dda2_line_interpolator 90 class dda2_line_interpolator 91 { 92 public: 93 typedef int save_data_type; 94 enum save_size_e { save_size = 2 }; 95 96 //-------------------------------------------------------------------- dda2_line_interpolator()97 dda2_line_interpolator() {} 98 99 //-------------------------------------------- Forward-adjusted line dda2_line_interpolator(int y1,int y2,int count)100 dda2_line_interpolator(int y1, int y2, int count) : 101 m_cnt(count <= 0 ? 1 : count), 102 m_lft((y2 - y1) / m_cnt), 103 m_rem((y2 - y1) % m_cnt), 104 m_mod(m_rem), 105 m_y(y1) 106 { 107 if(m_mod <= 0) 108 { 109 m_mod += count; 110 m_rem += count; 111 m_lft--; 112 } 113 m_mod -= count; 114 } 115 116 //-------------------------------------------- Backward-adjusted line dda2_line_interpolator(int y1,int y2,int count,int)117 dda2_line_interpolator(int y1, int y2, int count, int) : 118 m_cnt(count <= 0 ? 1 : count), 119 m_lft((y2 - y1) / m_cnt), 120 m_rem((y2 - y1) % m_cnt), 121 m_mod(m_rem), 122 m_y(y1) 123 { 124 if(m_mod <= 0) 125 { 126 m_mod += count; 127 m_rem += count; 128 m_lft--; 129 } 130 } 131 132 //-------------------------------------------- Backward-adjusted line dda2_line_interpolator(int y,int count)133 dda2_line_interpolator(int y, int count) : 134 m_cnt(count <= 0 ? 1 : count), 135 m_lft(y / m_cnt), 136 m_rem(y % m_cnt), 137 m_mod(m_rem), 138 m_y(0) 139 { 140 if(m_mod <= 0) 141 { 142 m_mod += count; 143 m_rem += count; 144 m_lft--; 145 } 146 } 147 148 149 //-------------------------------------------------------------------- save(save_data_type * data)150 void save(save_data_type* data) const 151 { 152 data[0] = m_mod; 153 data[1] = m_y; 154 } 155 156 //-------------------------------------------------------------------- load(const save_data_type * data)157 void load(const save_data_type* data) 158 { 159 m_mod = data[0]; 160 m_y = data[1]; 161 } 162 163 //-------------------------------------------------------------------- 164 void operator++() 165 { 166 m_mod += m_rem; 167 m_y += m_lft; 168 if(m_mod > 0) 169 { 170 m_mod -= m_cnt; 171 m_y++; 172 } 173 } 174 175 //-------------------------------------------------------------------- 176 void operator--() 177 { 178 if(m_mod <= m_rem) 179 { 180 m_mod += m_cnt; 181 m_y--; 182 } 183 m_mod -= m_rem; 184 m_y -= m_lft; 185 } 186 187 //-------------------------------------------------------------------- adjust_forward()188 void adjust_forward() 189 { 190 m_mod -= m_cnt; 191 } 192 193 //-------------------------------------------------------------------- adjust_backward()194 void adjust_backward() 195 { 196 m_mod += m_cnt; 197 } 198 199 //-------------------------------------------------------------------- mod()200 int mod() const { return m_mod; } rem()201 int rem() const { return m_rem; } lft()202 int lft() const { return m_lft; } 203 204 //-------------------------------------------------------------------- y()205 int y() const { return m_y; } 206 207 private: 208 int m_cnt; 209 int m_lft; 210 int m_rem; 211 int m_mod; 212 int m_y; 213 }; 214 215 216 217 218 219 220 221 //---------------------------------------------line_bresenham_interpolator 222 class line_bresenham_interpolator 223 { 224 public: 225 enum subpixel_scale_e 226 { 227 subpixel_shift = 8, 228 subpixel_scale = 1 << subpixel_shift, 229 subpixel_mask = subpixel_scale - 1 230 }; 231 232 //-------------------------------------------------------------------- line_lr(int v)233 static int line_lr(int v) { return v >> subpixel_shift; } 234 235 //-------------------------------------------------------------------- line_bresenham_interpolator(int x1,int y1,int x2,int y2)236 line_bresenham_interpolator(int x1, int y1, int x2, int y2) : 237 m_x1_lr(line_lr(x1)), 238 m_y1_lr(line_lr(y1)), 239 m_x2_lr(line_lr(x2)), 240 m_y2_lr(line_lr(y2)), 241 m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)), 242 m_len(m_ver ? abs(m_y2_lr - m_y1_lr) : 243 abs(m_x2_lr - m_x1_lr)), 244 m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)), 245 m_interpolator(m_ver ? x1 : y1, 246 m_ver ? x2 : y2, 247 m_len) 248 { 249 } 250 251 //-------------------------------------------------------------------- is_ver()252 bool is_ver() const { return m_ver; } len()253 unsigned len() const { return m_len; } inc()254 int inc() const { return m_inc; } 255 256 //-------------------------------------------------------------------- hstep()257 void hstep() 258 { 259 ++m_interpolator; 260 m_x1_lr += m_inc; 261 } 262 263 //-------------------------------------------------------------------- vstep()264 void vstep() 265 { 266 ++m_interpolator; 267 m_y1_lr += m_inc; 268 } 269 270 //-------------------------------------------------------------------- x1()271 int x1() const { return m_x1_lr; } y1()272 int y1() const { return m_y1_lr; } x2()273 int x2() const { return line_lr(m_interpolator.y()); } y2()274 int y2() const { return line_lr(m_interpolator.y()); } x2_hr()275 int x2_hr() const { return m_interpolator.y(); } y2_hr()276 int y2_hr() const { return m_interpolator.y(); } 277 278 private: 279 int m_x1_lr; 280 int m_y1_lr; 281 int m_x2_lr; 282 int m_y2_lr; 283 bool m_ver; 284 unsigned m_len; 285 int m_inc; 286 dda2_line_interpolator m_interpolator; 287 288 }; 289 290 291 } 292 293 294 295 #endif 296