123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- //----------------------------------------------------------------------------
- // Anti-Grain Geometry - Version 2.4
- // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
- //
- // Permission to copy, use, modify, sell and distribute this software
- // is granted provided this copyright notice appears in all copies.
- // This software is provided "as is" without express or implied
- // warranty, and with no claim as to its suitability for any purpose.
- //
- //----------------------------------------------------------------------------
- // Contact: mcseem@antigrain.com
- // mcseemagg@yahoo.com
- // http://www.antigrain.com
- //----------------------------------------------------------------------------
- //
- // classes dda_line_interpolator, dda2_line_interpolator
- //
- //----------------------------------------------------------------------------
- #ifndef AGG_DDA_LINE_INCLUDED
- #define AGG_DDA_LINE_INCLUDED
- #include <stdlib.h>
- #include "agg_basics.h"
- namespace agg
- {
- //===================================================dda_line_interpolator
- template<int FractionShift, int YShift=0> class dda_line_interpolator
- {
- public:
- //--------------------------------------------------------------------
- dda_line_interpolator() {}
- //--------------------------------------------------------------------
- dda_line_interpolator(int y1, int y2, unsigned count) :
- m_y(y1),
- m_inc(((y2 - y1) << FractionShift) / int(count)),
- m_dy(0)
- {
- }
- //--------------------------------------------------------------------
- void operator ++ ()
- {
- m_dy += m_inc;
- }
- //--------------------------------------------------------------------
- void operator -- ()
- {
- m_dy -= m_inc;
- }
- //--------------------------------------------------------------------
- void operator += (unsigned n)
- {
- m_dy += m_inc * n;
- }
- //--------------------------------------------------------------------
- void operator -= (unsigned n)
- {
- m_dy -= m_inc * n;
- }
- //--------------------------------------------------------------------
- int y() const { return m_y + (m_dy >> (FractionShift-YShift)); }
- int dy() const { return m_dy; }
- private:
- int m_y;
- int m_inc;
- int m_dy;
- };
- //=================================================dda2_line_interpolator
- class dda2_line_interpolator
- {
- public:
- typedef int save_data_type;
- enum save_size_e { save_size = 2 };
- //--------------------------------------------------------------------
- dda2_line_interpolator() {}
- //-------------------------------------------- Forward-adjusted line
- dda2_line_interpolator(int y1, int y2, int count) :
- m_cnt(count <= 0 ? 1 : count),
- m_lft((y2 - y1) / m_cnt),
- m_rem((y2 - y1) % m_cnt),
- m_mod(m_rem),
- m_y(y1)
- {
- if(m_mod <= 0)
- {
- m_mod += count;
- m_rem += count;
- m_lft--;
- }
- m_mod -= count;
- }
- //-------------------------------------------- Backward-adjusted line
- dda2_line_interpolator(int y1, int y2, int count, int) :
- m_cnt(count <= 0 ? 1 : count),
- m_lft((y2 - y1) / m_cnt),
- m_rem((y2 - y1) % m_cnt),
- m_mod(m_rem),
- m_y(y1)
- {
- if(m_mod <= 0)
- {
- m_mod += count;
- m_rem += count;
- m_lft--;
- }
- }
- //-------------------------------------------- Backward-adjusted line
- dda2_line_interpolator(int y, int count) :
- m_cnt(count <= 0 ? 1 : count),
- m_lft(y / m_cnt),
- m_rem(y % m_cnt),
- m_mod(m_rem),
- m_y(0)
- {
- if(m_mod <= 0)
- {
- m_mod += count;
- m_rem += count;
- m_lft--;
- }
- }
- //--------------------------------------------------------------------
- void save(save_data_type* data) const
- {
- data[0] = m_mod;
- data[1] = m_y;
- }
- //--------------------------------------------------------------------
- void load(const save_data_type* data)
- {
- m_mod = data[0];
- m_y = data[1];
- }
- //--------------------------------------------------------------------
- void operator++()
- {
- m_mod += m_rem;
- m_y += m_lft;
- if(m_mod > 0)
- {
- m_mod -= m_cnt;
- m_y++;
- }
- }
- //--------------------------------------------------------------------
- void operator--()
- {
- if(m_mod <= m_rem)
- {
- m_mod += m_cnt;
- m_y--;
- }
- m_mod -= m_rem;
- m_y -= m_lft;
- }
- //--------------------------------------------------------------------
- void adjust_forward()
- {
- m_mod -= m_cnt;
- }
- //--------------------------------------------------------------------
- void adjust_backward()
- {
- m_mod += m_cnt;
- }
- //--------------------------------------------------------------------
- int mod() const { return m_mod; }
- int rem() const { return m_rem; }
- int lft() const { return m_lft; }
- //--------------------------------------------------------------------
- int y() const { return m_y; }
- private:
- int m_cnt;
- int m_lft;
- int m_rem;
- int m_mod;
- int m_y;
- };
- //---------------------------------------------line_bresenham_interpolator
- class line_bresenham_interpolator
- {
- public:
- enum subpixel_scale_e
- {
- subpixel_shift = 8,
- subpixel_scale = 1 << subpixel_shift,
- subpixel_mask = subpixel_scale - 1
- };
- //--------------------------------------------------------------------
- static int line_lr(int v) { return v >> subpixel_shift; }
- //--------------------------------------------------------------------
- line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
- m_x1_lr(line_lr(x1)),
- m_y1_lr(line_lr(y1)),
- m_x2_lr(line_lr(x2)),
- m_y2_lr(line_lr(y2)),
- m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
- m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
- abs(m_x2_lr - m_x1_lr)),
- m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
- m_interpolator(m_ver ? x1 : y1,
- m_ver ? x2 : y2,
- m_len)
- {
- }
-
- //--------------------------------------------------------------------
- bool is_ver() const { return m_ver; }
- unsigned len() const { return m_len; }
- int inc() const { return m_inc; }
- //--------------------------------------------------------------------
- void hstep()
- {
- ++m_interpolator;
- m_x1_lr += m_inc;
- }
- //--------------------------------------------------------------------
- void vstep()
- {
- ++m_interpolator;
- m_y1_lr += m_inc;
- }
- //--------------------------------------------------------------------
- int x1() const { return m_x1_lr; }
- int y1() const { return m_y1_lr; }
- int x2() const { return line_lr(m_interpolator.y()); }
- int y2() const { return line_lr(m_interpolator.y()); }
- int x2_hr() const { return m_interpolator.y(); }
- int y2_hr() const { return m_interpolator.y(); }
- private:
- int m_x1_lr;
- int m_y1_lr;
- int m_x2_lr;
- int m_y2_lr;
- bool m_ver;
- unsigned m_len;
- int m_inc;
- dda2_line_interpolator m_interpolator;
- };
- }
- #endif
|