mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
324 lines
8.5 KiB
C++
324 lines
8.5 KiB
C++
//----------------------------------------------------------------------------
|
|
// 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 <cstdlib>
|
|
#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(std::abs(m_x2_lr - m_x1_lr) < std::abs(m_y2_lr - m_y1_lr)),
|
|
m_len(m_ver ? std::abs(m_y2_lr - m_y1_lr)
|
|
: std::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
|