00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef AGG_DDA_LINE_INCLUDED
00021 #define AGG_DDA_LINE_INCLUDED
00022
00023 #include <stdlib.h>
00024 #include "agg_basics.h"
00025
00026 namespace agg
00027 {
00028
00029
00030 template<int FractionShift, int YShift=0> class dda_line_interpolator
00031 {
00032 public:
00033
00034 dda_line_interpolator() {}
00035
00036
00037 dda_line_interpolator(int y1, int y2, unsigned count) :
00038 m_y(y1),
00039 m_inc(((y2 - y1) << FractionShift) / int(count)),
00040 m_dy(0)
00041 {
00042 }
00043
00044
00045 void operator ++ ()
00046 {
00047 m_dy += m_inc;
00048 }
00049
00050
00051 void operator -- ()
00052 {
00053 m_dy -= m_inc;
00054 }
00055
00056
00057 void operator += (unsigned n)
00058 {
00059 m_dy += m_inc * n;
00060 }
00061
00062
00063 void operator -= (unsigned n)
00064 {
00065 m_dy -= m_inc * n;
00066 }
00067
00068
00069
00070 int y() const { return m_y + (m_dy >> (FractionShift-YShift)); }
00071 int dy() const { return m_dy; }
00072
00073
00074 private:
00075 int m_y;
00076 int m_inc;
00077 int m_dy;
00078 };
00079
00080
00081
00082
00083
00084
00085 class dda2_line_interpolator
00086 {
00087 public:
00088 typedef int save_data_type;
00089 enum { save_size = 2 };
00090
00091
00092 dda2_line_interpolator() {}
00093
00094
00095 dda2_line_interpolator(int y1, int y2, int count) :
00096 m_cnt(count <= 0 ? 1 : count),
00097 m_lft((y2 - y1) / m_cnt),
00098 m_rem((y2 - y1) % m_cnt),
00099 m_mod(m_rem),
00100 m_y(y1)
00101 {
00102 if(m_mod <= 0)
00103 {
00104 m_mod += count;
00105 m_rem += count;
00106 m_lft--;
00107 }
00108 m_mod -= count;
00109 }
00110
00111
00112 dda2_line_interpolator(int y1, int y2, int count, int) :
00113 m_cnt(count <= 0 ? 1 : count),
00114 m_lft((y2 - y1) / m_cnt),
00115 m_rem((y2 - y1) % m_cnt),
00116 m_mod(m_rem),
00117 m_y(y1)
00118 {
00119 if(m_mod <= 0)
00120 {
00121 m_mod += count;
00122 m_rem += count;
00123 m_lft--;
00124 }
00125 }
00126
00127
00128 dda2_line_interpolator(int y, int count) :
00129 m_cnt(count <= 0 ? 1 : count),
00130 m_lft(y / m_cnt),
00131 m_rem(y % m_cnt),
00132 m_mod(m_rem),
00133 m_y(0)
00134 {
00135 if(m_mod <= 0)
00136 {
00137 m_mod += count;
00138 m_rem += count;
00139 m_lft--;
00140 }
00141 }
00142
00143
00144
00145 void save(save_data_type* data) const
00146 {
00147 data[0] = m_mod;
00148 data[1] = m_y;
00149 }
00150
00151
00152 void load(const save_data_type* data)
00153 {
00154 m_mod = data[0];
00155 m_y = data[1];
00156 }
00157
00158
00159 void operator++()
00160 {
00161 m_mod += m_rem;
00162 m_y += m_lft;
00163 if(m_mod > 0)
00164 {
00165 m_mod -= m_cnt;
00166 m_y++;
00167 }
00168 }
00169
00170
00171 void operator--()
00172 {
00173 if(m_mod <= m_rem)
00174 {
00175 m_mod += m_cnt;
00176 m_y--;
00177 }
00178 m_mod -= m_rem;
00179 m_y -= m_lft;
00180 }
00181
00182
00183 void adjust_forward()
00184 {
00185 m_mod -= m_cnt;
00186 }
00187
00188
00189 void adjust_backward()
00190 {
00191 m_mod += m_cnt;
00192 }
00193
00194
00195 int mod() const { return m_mod; }
00196 int rem() const { return m_rem; }
00197 int lft() const { return m_lft; }
00198
00199
00200 int y() const { return m_y; }
00201
00202 private:
00203 int m_cnt;
00204 int m_lft;
00205 int m_rem;
00206 int m_mod;
00207 int m_y;
00208 };
00209
00210
00211
00212
00213
00214
00215
00216
00217 class line_bresenham_interpolator
00218 {
00219 public:
00220 enum
00221 {
00222 subpixel_shift = 8,
00223 subpixel_size = 1 << subpixel_shift,
00224 subpixel_mask = subpixel_size - 1
00225 };
00226
00227
00228 static int line_lr(int v) { return v >> subpixel_shift; }
00229
00230
00231 line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
00232 m_x1_lr(line_lr(x1)),
00233 m_y1_lr(line_lr(y1)),
00234 m_x2_lr(line_lr(x2)),
00235 m_y2_lr(line_lr(y2)),
00236 m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
00237 m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
00238 abs(m_x2_lr - m_x1_lr)),
00239 m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
00240 m_interpolator(m_ver ? x1 : y1,
00241 m_ver ? x2 : y2,
00242 m_len)
00243 {
00244 }
00245
00246
00247 bool is_ver() const { return m_ver; }
00248 unsigned len() const { return m_len; }
00249 int inc() const { return m_inc; }
00250
00251
00252 void hstep()
00253 {
00254 ++m_interpolator;
00255 m_x1_lr += m_inc;
00256 }
00257
00258
00259 void vstep()
00260 {
00261 ++m_interpolator;
00262 m_y1_lr += m_inc;
00263 }
00264
00265
00266 int x1() const { return m_x1_lr; }
00267 int y1() const { return m_y1_lr; }
00268 int x2() const { return line_lr(m_interpolator.y()); }
00269 int y2() const { return line_lr(m_interpolator.y()); }
00270 int x2_hr() const { return m_interpolator.y(); }
00271 int y2_hr() const { return m_interpolator.y(); }
00272
00273 private:
00274 int m_x1_lr;
00275 int m_y1_lr;
00276 int m_x2_lr;
00277 int m_y2_lr;
00278 bool m_ver;
00279 unsigned m_len;
00280 int m_inc;
00281 dda2_line_interpolator m_interpolator;
00282
00283 };
00284
00285
00286 }
00287
00288
00289
00290 #endif