You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
8.3 KiB
290 lines
8.3 KiB
//---------------------------------------------------------------------------- |
|
// 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
|
|
|