* long overdue update to AGG 2.4

* removed the useless parts of AGG (which are only needed for the
  interactive examples)
* make sure to jam -a libagg.a to solve any linking issues


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17838 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2006-06-14 14:30:17 +00:00
parent a58450492a
commit e39da397f5
229 changed files with 23117 additions and 18461 deletions
+24 -24
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -49,7 +49,7 @@ namespace agg
public:
typedef int8u cover_type;
typedef alpha_mask_u8<Step, Offset, MaskF> self_type;
enum
enum cover_scale_e
{
cover_shift = 8,
cover_none = 0,
@@ -70,10 +70,10 @@ namespace agg
{
if(x >= 0 && y >= 0 &&
x < (int)m_rbuf->width() &&
y <= (int)m_rbuf->height())
y < (int)m_rbuf->height())
{
return (cover_type)m_mask_function.calculate(
m_rbuf->row(y) + x * Step + Offset);
m_rbuf->row_ptr(y) + x * Step + Offset);
}
return 0;
}
@@ -83,11 +83,11 @@ namespace agg
{
if(x >= 0 && y >= 0 &&
x < (int)m_rbuf->width() &&
y <= (int)m_rbuf->height())
y < (int)m_rbuf->height())
{
return (cover_type)((val *
return (cover_type)((cover_full + val *
m_mask_function.calculate(
m_rbuf->row(y) + x * Step + Offset)) >>
m_rbuf->row_ptr(y) + x * Step + Offset)) >>
cover_shift);
}
return 0;
@@ -134,7 +134,7 @@ namespace agg
memset(covers + count, 0, rest * sizeof(cover_type));
}
const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers++ = (cover_type)m_mask_function.calculate(mask);
@@ -184,10 +184,10 @@ namespace agg
memset(covers + count, 0, rest * sizeof(cover_type));
}
const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers = (cover_type)(((*covers) *
*covers = (cover_type)((cover_full + (*covers) *
m_mask_function.calculate(mask)) >>
cover_shift);
++covers;
@@ -236,7 +236,7 @@ namespace agg
memset(covers + count, 0, rest * sizeof(cover_type));
}
const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers++ = (cover_type)m_mask_function.calculate(mask);
@@ -285,10 +285,10 @@ namespace agg
memset(covers + count, 0, rest * sizeof(cover_type));
}
const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers = (cover_type)(((*covers) *
*covers = (cover_type)((cover_full + (*covers) *
m_mask_function.calculate(mask)) >>
cover_shift);
++covers;
@@ -353,7 +353,7 @@ namespace agg
public:
typedef int8u cover_type;
typedef amask_no_clip_u8<Step, Offset, MaskF> self_type;
enum
enum cover_scale_e
{
cover_shift = 8,
cover_none = 0,
@@ -373,16 +373,16 @@ namespace agg
cover_type pixel(int x, int y) const
{
return (cover_type)m_mask_function.calculate(
m_rbuf->row(y) + x * Step + Offset);
m_rbuf->row_ptr(y) + x * Step + Offset);
}
//--------------------------------------------------------------------
cover_type combine_pixel(int x, int y, cover_type val) const
{
return (cover_type)((val *
return (cover_type)((cover_full + val *
m_mask_function.calculate(
m_rbuf->row(y) + x * Step + Offset)) >>
m_rbuf->row_ptr(y) + x * Step + Offset)) >>
cover_shift);
}
@@ -390,7 +390,7 @@ namespace agg
//--------------------------------------------------------------------
void fill_hspan(int x, int y, cover_type* dst, int num_pix) const
{
const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst++ = (cover_type)m_mask_function.calculate(mask);
@@ -404,10 +404,10 @@ namespace agg
//--------------------------------------------------------------------
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
{
const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst = (cover_type)(((*dst) *
*dst = (cover_type)((cover_full + (*dst) *
m_mask_function.calculate(mask)) >>
cover_shift);
++dst;
@@ -420,7 +420,7 @@ namespace agg
//--------------------------------------------------------------------
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
{
const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst++ = (cover_type)m_mask_function.calculate(mask);
@@ -433,10 +433,10 @@ namespace agg
//--------------------------------------------------------------------
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
{
const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst = (cover_type)(((*dst) *
*dst = (cover_type)((cover_full + (*dst) *
m_mask_function.calculate(mask)) >>
cover_shift);
++dst;
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+378 -116
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -22,38 +22,191 @@
namespace agg
{
//-------------------------------------------------------pod_array_adaptor
template<class T> class pod_array_adaptor
{
public:
typedef T value_type;
pod_array_adaptor(T* array, unsigned size) :
m_array(array), m_size(size) {}
unsigned size() const { return m_size; }
const T& operator [] (unsigned i) const { return m_array[i]; }
T& operator [] (unsigned i) { return m_array[i]; }
const T& at(unsigned i) const { return m_array[i]; }
T& at(unsigned i) { return m_array[i]; }
T value_at(unsigned i) const { return m_array[i]; }
private:
T* m_array;
unsigned m_size;
};
//---------------------------------------------------------pod_auto_array
template<class T, unsigned Size> class pod_auto_array
{
public:
typedef T value_type;
typedef pod_auto_array<T, Size> self_type;
pod_auto_array() {}
explicit pod_auto_array(const T* c)
{
memcpy(m_array, c, sizeof(T) * Size);
}
const self_type& operator = (const T* c)
{
memcpy(m_array, c, sizeof(T) * Size);
return *this;
}
static unsigned size() { return Size; }
const T& operator [] (unsigned i) const { return m_array[i]; }
T& operator [] (unsigned i) { return m_array[i]; }
const T& at(unsigned i) const { return m_array[i]; }
T& at(unsigned i) { return m_array[i]; }
T value_at(unsigned i) const { return m_array[i]; }
private:
T m_array[Size];
};
//--------------------------------------------------------pod_auto_vector
template<class T, unsigned Size> class pod_auto_vector
{
public:
typedef T value_type;
typedef pod_auto_vector<T, Size> self_type;
pod_auto_vector() : m_size(0) {}
void remove_all() { m_size = 0; }
void clear() { m_size = 0; }
void add(const T& v) { m_array[m_size++] = v; }
void push_back(const T& v) { m_array[m_size++] = v; }
void inc_size(unsigned size) { m_size += size; }
unsigned size() const { return m_size; }
const T& operator [] (unsigned i) const { return m_array[i]; }
T& operator [] (unsigned i) { return m_array[i]; }
const T& at(unsigned i) const { return m_array[i]; }
T& at(unsigned i) { return m_array[i]; }
T value_at(unsigned i) const { return m_array[i]; }
private:
T m_array[Size];
unsigned m_size;
};
//---------------------------------------------------------------pod_array
// A simple class template to store Plain Old Data, a vector
// of a fixed size. The data is continous in memory
//------------------------------------------------------------------------
template<class T> class pod_array
{
public:
typedef T value_type;
typedef pod_array<T> self_type;
~pod_array() { delete [] m_array; }
pod_array() : m_size(0), m_capacity(0), m_array(0) {}
pod_array(unsigned cap, unsigned extra_tail=0);
~pod_array() { pod_allocator<T>::deallocate(m_array, m_size); }
pod_array() : m_array(0), m_size(0) {}
pod_array(unsigned size) :
m_array(pod_allocator<T>::allocate(size)),
m_size(size)
{}
pod_array(const self_type& v) :
m_array(pod_allocator<T>::allocate(v.m_size)),
m_size(v.m_size)
{
memcpy(m_array, v.m_array, sizeof(T) * m_size);
}
void resize(unsigned size)
{
if(size != m_size)
{
pod_allocator<T>::deallocate(m_array, m_size);
m_array = pod_allocator<T>::allocate(m_size = size);
}
}
const self_type& operator = (const self_type& v)
{
resize(v.size());
memcpy(m_array, v.m_array, sizeof(T) * m_size);
return *this;
}
unsigned size() const { return m_size; }
const T& operator [] (unsigned i) const { return m_array[i]; }
T& operator [] (unsigned i) { return m_array[i]; }
const T& at(unsigned i) const { return m_array[i]; }
T& at(unsigned i) { return m_array[i]; }
T value_at(unsigned i) const { return m_array[i]; }
const T* data() const { return m_array; }
T* data() { return m_array; }
private:
T* m_array;
unsigned m_size;
};
//--------------------------------------------------------------pod_vector
// A simple class template to store Plain Old Data, a vector
// of a fixed size. The data is continous in memory
//------------------------------------------------------------------------
template<class T> class pod_vector
{
public:
typedef T value_type;
~pod_vector() { pod_allocator<T>::deallocate(m_array, m_capacity); }
pod_vector() : m_size(0), m_capacity(0), m_array(0) {}
pod_vector(unsigned cap, unsigned extra_tail=0);
// Copying
pod_array(const pod_array<T>&);
const pod_array<T>& operator = (const pod_array<T>&);
pod_vector(const pod_vector<T>&);
const pod_vector<T>& operator = (const pod_vector<T>&);
unsigned capacity() const { return m_capacity; }
// Set new capacity. All data is lost, size is set to zero.
void capacity(unsigned cap, unsigned extra_tail=0);
unsigned capacity() const { return m_capacity; }
// Allocate n elements. All data is lost,
// but elements can be accessed in range 0...size-1.
void allocate(unsigned size, unsigned extra_tail=0);
// Resize keeping the content.
void resize(unsigned new_size);
void add(const T& v) { m_array[m_size++] = v; }
void inc_size(unsigned size) { m_size += size; }
unsigned size() const { return m_size; }
unsigned byte_size() const { return m_size * sizeof(T); }
void zero()
{
memset(m_array, 0, sizeof(T) * m_size);
}
void add(const T& v) { m_array[m_size++] = v; }
void push_back(const T& v) { m_array[m_size++] = v; }
void insert_at(unsigned pos, const T& val);
void inc_size(unsigned size) { m_size += size; }
unsigned size() const { return m_size; }
unsigned byte_size() const { return m_size * sizeof(T); }
void serialize(int8u* ptr) const;
void deserialize(const int8u* data, unsigned byte_size);
const T& operator [] (unsigned idx) const { return m_array[idx]; }
T& operator [] (unsigned idx) { return m_array[idx]; }
const T& operator [] (unsigned i) const { return m_array[i]; }
T& operator [] (unsigned i) { return m_array[i]; }
const T& at(unsigned i) const { return m_array[i]; }
T& at(unsigned i) { return m_array[i]; }
T value_at(unsigned i) const { return m_array[i]; }
const T* data() const { return m_array; }
T* data() { return m_array; }
void remove_all() { m_size = 0; }
void clear() { m_size = 0; }
void cut_at(unsigned num) { if(num < m_size) m_size = num; }
private:
@@ -64,28 +217,37 @@ namespace agg
//------------------------------------------------------------------------
template<class T>
void pod_array<T>::capacity(unsigned cap, unsigned extra_tail)
void pod_vector<T>::capacity(unsigned cap, unsigned extra_tail)
{
m_size = 0;
if(cap > m_capacity)
{
delete [] m_array;
pod_allocator<T>::deallocate(m_array, m_capacity);
m_capacity = cap + extra_tail;
m_array = m_capacity ? new T [m_capacity] : 0;
m_array = m_capacity ? pod_allocator<T>::allocate(m_capacity) : 0;
}
}
//------------------------------------------------------------------------
template<class T>
void pod_array<T>::resize(unsigned new_size)
void pod_vector<T>::allocate(unsigned size, unsigned extra_tail)
{
capacity(size, extra_tail);
m_size = size;
}
//------------------------------------------------------------------------
template<class T>
void pod_vector<T>::resize(unsigned new_size)
{
if(new_size > m_size)
{
if(new_size > m_capacity)
{
T* data = new T[new_size];
T* data = pod_allocator<T>::allocate(new_size);
memcpy(data, m_array, m_size * sizeof(T));
delete [] m_array;
pod_allocator<T>::deallocate(m_array, m_capacity);
m_array = data;
}
}
@@ -96,81 +258,75 @@ namespace agg
}
//------------------------------------------------------------------------
template<class T> pod_array<T>::pod_array(unsigned cap, unsigned extra_tail) :
m_size(0), m_capacity(0), m_array(0)
{
capacity(cap, extra_tail);
}
template<class T> pod_vector<T>::pod_vector(unsigned cap, unsigned extra_tail) :
m_size(0),
m_capacity(cap + extra_tail),
m_array(pod_allocator<T>::allocate(m_capacity)) {}
//------------------------------------------------------------------------
template<class T> pod_array<T>::pod_array(const pod_array<T>& v) :
template<class T> pod_vector<T>::pod_vector(const pod_vector<T>& v) :
m_size(v.m_size),
m_capacity(v.m_capacity),
m_array(v.m_capacity ? new T [v.m_capacity] : 0)
m_array(v.m_capacity ? pod_allocator<T>::allocate(v.m_capacity) : 0)
{
memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
}
//------------------------------------------------------------------------
template<class T> const pod_array<T>&
pod_array<T>::operator = (const pod_array<T>&v)
template<class T> const pod_vector<T>&
pod_vector<T>::operator = (const pod_vector<T>&v)
{
capacity(v.m_capacity);
allocate(v.m_size);
if(v.m_size) memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
return *this;
}
//------------------------------------------------------------------------
template<class T> void pod_array<T>::serialize(int8u* ptr) const
template<class T> void pod_vector<T>::serialize(int8u* ptr) const
{
if(m_size) memcpy(ptr, m_array, m_size * sizeof(T));
}
//------------------------------------------------------------------------
template<class T>
void pod_array<T>::deserialize(const int8u* data, unsigned byte_size)
void pod_vector<T>::deserialize(const int8u* data, unsigned byte_size)
{
byte_size /= sizeof(T);
capacity(byte_size);
allocate(byte_size);
if(byte_size) memcpy(m_array, data, byte_size * sizeof(T));
}
//------------------------------------------------------------------------
template<class T> class pod_array_adaptor
template<class T>
void pod_vector<T>::insert_at(unsigned pos, const T& val)
{
public:
typedef T value_type;
pod_array_adaptor(T* array, unsigned size) :
m_array(array), m_size(size) {}
if(pos >= m_size)
{
m_array[m_size] = val;
}
else
{
memmove(m_array + pos + 1, m_array + pos, (m_size - pos) * sizeof(T));
m_array[pos] = val;
}
++m_size;
}
unsigned size() const { return m_size; }
const T& operator [] (unsigned idx) const { return m_array[idx]; }
T& operator [] (unsigned idx) { return m_array[idx]; }
private:
T* m_array;
unsigned m_size;
};
//---------------------------------------------------------------pod_deque
//---------------------------------------------------------------pod_bvector
// A simple class template to store Plain Old Data, similar to std::deque
// It doesn't reallocate memory but instead, uses blocks of data of size
// of (1 << S), that is, power of two. The data is NOT continuous in memory,
// of (1 << S), that is, power of two. The data is NOT contiguous in memory,
// so the only valid access method is operator [] or curr(), prev(), next()
//
// There reallocs occure only when the pool of pointers to blocks needs
// to be extended (it happens very rear). You can control the value
// to be extended (it happens very rarely). You can control the value
// of increment to reallocate the pointer buffer. See the second constructor.
// By default, the incremeent value equals (1 << S), i.e., the block size.
//------------------------------------------------------------------------
template<class T, unsigned S=6> class pod_deque
template<class T, unsigned S=6> class pod_bvector
{
public:
enum
enum block_scale_e
{
block_shift = S,
block_size = 1 << block_shift,
@@ -179,18 +335,20 @@ namespace agg
typedef T value_type;
~pod_deque();
pod_deque();
pod_deque(unsigned block_ptr_inc);
~pod_bvector();
pod_bvector();
pod_bvector(unsigned block_ptr_inc);
// Copying
pod_deque(const pod_deque<T, S>& v);
const pod_deque<T, S>& operator = (const pod_deque<T, S>& v);
pod_bvector(const pod_bvector<T, S>& v);
const pod_bvector<T, S>& operator = (const pod_bvector<T, S>& v);
void remove_all() { m_size = 0; }
void free_all() { free_tail(0); }
void clear() { m_size = 0; }
void free_all() { free_tail(0); }
void free_tail(unsigned size);
void add(const T& val);
void push_back(const T& val) { add(val); }
void modify_last(const T& val);
void remove_last();
@@ -220,14 +378,29 @@ namespace agg
unsigned size() const { return m_size; }
const T& operator [] (unsigned idx) const
const T& operator [] (unsigned i) const
{
return m_blocks[idx >> block_shift][idx & block_mask];
return m_blocks[i >> block_shift][i & block_mask];
}
T& operator [] (unsigned idx)
T& operator [] (unsigned i)
{
return m_blocks[idx >> block_shift][idx & block_mask];
return m_blocks[i >> block_shift][i & block_mask];
}
const T& at(unsigned i) const
{
return m_blocks[i >> block_shift][i & block_mask];
}
T& at(unsigned i)
{
return m_blocks[i >> block_shift][i & block_mask];
}
T value_at(unsigned i) const
{
return m_blocks[i >> block_shift][i & block_mask];
}
const T& curr(unsigned idx) const
@@ -338,31 +511,37 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S> pod_deque<T, S>::~pod_deque()
template<class T, unsigned S> pod_bvector<T, S>::~pod_bvector()
{
if(m_num_blocks)
{
T** blk = m_blocks + m_num_blocks - 1;
while(m_num_blocks--)
{
delete [] *blk;
pod_allocator<T>::deallocate(*blk, block_size);
--blk;
}
delete [] m_blocks;
}
pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
}
//------------------------------------------------------------------------
template<class T, unsigned S>
void pod_deque<T, S>::free_tail(unsigned size)
void pod_bvector<T, S>::free_tail(unsigned size)
{
if(size < m_size)
{
unsigned nb = (size + block_mask) >> block_shift;
while(m_num_blocks > nb)
{
delete [] m_blocks[--m_num_blocks];
pod_allocator<T>::deallocate(m_blocks[--m_num_blocks], block_size);
}
if(m_num_blocks == 0)
{
pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
m_blocks = 0;
m_max_blocks = 0;
}
m_size = size;
}
@@ -370,7 +549,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S> pod_deque<T, S>::pod_deque() :
template<class T, unsigned S> pod_bvector<T, S>::pod_bvector() :
m_size(0),
m_num_blocks(0),
m_max_blocks(0),
@@ -382,7 +561,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
pod_deque<T, S>::pod_deque(unsigned block_ptr_inc) :
pod_bvector<T, S>::pod_bvector(unsigned block_ptr_inc) :
m_size(0),
m_num_blocks(0),
m_max_blocks(0),
@@ -394,17 +573,19 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
pod_deque<T, S>::pod_deque(const pod_deque<T, S>& v) :
pod_bvector<T, S>::pod_bvector(const pod_bvector<T, S>& v) :
m_size(v.m_size),
m_num_blocks(v.m_num_blocks),
m_max_blocks(v.m_max_blocks),
m_blocks(v.m_max_blocks ? new T* [v.m_max_blocks] : 0),
m_blocks(v.m_max_blocks ?
pod_allocator<T*>::allocate(v.m_max_blocks) :
0),
m_block_ptr_inc(v.m_block_ptr_inc)
{
unsigned i;
for(i = 0; i < v.m_num_blocks; ++i)
{
m_blocks[i] = new T [block_size];
m_blocks[i] = pod_allocator<T>::allocate(block_size);
memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T));
}
}
@@ -412,7 +593,8 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
const pod_deque<T, S>& pod_deque<T, S>::operator = (const pod_deque<T, S>& v)
const pod_bvector<T, S>&
pod_bvector<T, S>::operator = (const pod_bvector<T, S>& v)
{
unsigned i;
for(i = m_num_blocks; i < v.m_num_blocks; ++i)
@@ -430,11 +612,11 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
void pod_deque<T, S>::allocate_block(unsigned nb)
void pod_bvector<T, S>::allocate_block(unsigned nb)
{
if(nb >= m_max_blocks)
{
T** new_blocks = new T* [m_max_blocks + m_block_ptr_inc];
T** new_blocks = pod_allocator<T*>::allocate(m_max_blocks + m_block_ptr_inc);
if(m_blocks)
{
@@ -442,12 +624,12 @@ namespace agg
m_blocks,
m_num_blocks * sizeof(T*));
delete [] m_blocks;
pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
}
m_blocks = new_blocks;
m_max_blocks += m_block_ptr_inc;
}
m_blocks[nb] = new T [block_size];
m_blocks[nb] = pod_allocator<T>::allocate(block_size);
m_num_blocks++;
}
@@ -455,7 +637,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
inline T* pod_deque<T, S>::data_ptr()
inline T* pod_bvector<T, S>::data_ptr()
{
unsigned nb = m_size >> block_shift;
if(nb >= m_num_blocks)
@@ -469,7 +651,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
inline void pod_deque<T, S>::add(const T& val)
inline void pod_bvector<T, S>::add(const T& val)
{
*data_ptr() = val;
++m_size;
@@ -478,7 +660,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
inline void pod_deque<T, S>::remove_last()
inline void pod_bvector<T, S>::remove_last()
{
if(m_size) --m_size;
}
@@ -486,7 +668,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
void pod_deque<T, S>::modify_last(const T& val)
void pod_bvector<T, S>::modify_last(const T& val)
{
remove_last();
add(val);
@@ -495,7 +677,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
int pod_deque<T, S>::allocate_continuous_block(unsigned num_elements)
int pod_bvector<T, S>::allocate_continuous_block(unsigned num_elements)
{
if(num_elements < block_size)
{
@@ -525,7 +707,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
unsigned pod_deque<T, S>::byte_size() const
unsigned pod_bvector<T, S>::byte_size() const
{
return m_size * sizeof(T);
}
@@ -533,7 +715,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
void pod_deque<T, S>::serialize(int8u* ptr) const
void pod_bvector<T, S>::serialize(int8u* ptr) const
{
unsigned i;
for(i = 0; i < m_size; i++)
@@ -545,7 +727,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
void pod_deque<T, S>::deserialize(const int8u* data, unsigned byte_size)
void pod_bvector<T, S>::deserialize(const int8u* data, unsigned byte_size)
{
remove_all();
byte_size /= sizeof(T);
@@ -562,8 +744,8 @@ namespace agg
// Replace or add a number of elements starting from "start" position
//------------------------------------------------------------------------
template<class T, unsigned S>
void pod_deque<T, S>::deserialize(unsigned start, const T& empty_val,
const int8u* data, unsigned byte_size)
void pod_bvector<T, S>::deserialize(unsigned start, const T& empty_val,
const int8u* data, unsigned byte_size)
{
while(m_size < start)
{
@@ -588,7 +770,7 @@ namespace agg
}
//-----------------------------------------------------------pod_allocator
//---------------------------------------------------------block_allocator
// Allocator for arbitrary POD data. Most usable in different cache
// systems for efficient memory allocations.
// Memory is allocated with blocks of fixed size ("block_size" in
@@ -596,20 +778,26 @@ namespace agg
// creates a new block of the required size. However, the most efficient
// use is when the average reqired size is much less than the block size.
//------------------------------------------------------------------------
class pod_allocator
class block_allocator
{
struct block_type
{
int8u* data;
unsigned size;
};
public:
void remove_all()
{
if(m_num_blocks)
{
int8u** blk = m_blocks + m_num_blocks - 1;
block_type* blk = m_blocks + m_num_blocks - 1;
while(m_num_blocks--)
{
delete [] *blk;
pod_allocator<int8u>::deallocate(blk->data, blk->size);
--blk;
}
delete [] m_blocks;
pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks);
}
m_num_blocks = 0;
m_max_blocks = 0;
@@ -618,12 +806,12 @@ namespace agg
m_rest = 0;
}
~pod_allocator()
~block_allocator()
{
remove_all();
}
pod_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) :
block_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) :
m_block_size(block_size),
m_block_ptr_inc(block_ptr_inc),
m_num_blocks(0),
@@ -643,7 +831,9 @@ namespace agg
int8u* ptr = m_buf_ptr;
if(alignment > 1)
{
unsigned align = (alignment - unsigned((size_t)ptr) % alignment) % alignment;
unsigned align =
(alignment - unsigned((size_t)ptr) % alignment) % alignment;
size += align;
ptr += align;
if(size <= m_rest)
@@ -670,31 +860,36 @@ namespace agg
if(size < m_block_size) size = m_block_size;
if(m_num_blocks >= m_max_blocks)
{
int8u** new_blocks = new int8u* [m_max_blocks + m_block_ptr_inc];
block_type* new_blocks =
pod_allocator<block_type>::allocate(m_max_blocks + m_block_ptr_inc);
if(m_blocks)
{
memcpy(new_blocks,
m_blocks,
m_num_blocks * sizeof(int8u*));
delete [] m_blocks;
m_num_blocks * sizeof(block_type));
pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks);
}
m_blocks = new_blocks;
m_max_blocks += m_block_ptr_inc;
}
m_blocks[m_num_blocks] = m_buf_ptr = new int8u [size];
m_blocks[m_num_blocks].size = size;
m_blocks[m_num_blocks].data =
m_buf_ptr =
pod_allocator<int8u>::allocate(size);
m_num_blocks++;
m_rest = size;
}
unsigned m_block_size;
unsigned m_block_ptr_inc;
unsigned m_num_blocks;
unsigned m_max_blocks;
int8u** m_blocks;
int8u* m_buf_ptr;
unsigned m_rest;
unsigned m_block_size;
unsigned m_block_ptr_inc;
unsigned m_num_blocks;
unsigned m_max_blocks;
block_type* m_blocks;
int8u* m_buf_ptr;
unsigned m_rest;
};
@@ -705,7 +900,7 @@ namespace agg
//------------------------------------------------------------------------
enum
enum quick_sort_threshold_e
{
quick_sort_threshold = 9
};
@@ -829,7 +1024,7 @@ namespace agg
//------------------------------------------------------remove_duplicates
// Remove duplicates from a sorted array. It doesn't cut the the
// Remove duplicates from a sorted array. It doesn't cut the
// tail of the array, it just returns the number of remaining elements.
//-----------------------------------------------------------------------
template<class Array, class Equal>
@@ -849,9 +1044,76 @@ namespace agg
return j;
}
//--------------------------------------------------------invert_container
template<class Array> void invert_container(Array& arr)
{
int i = 0;
int j = arr.size() - 1;
while(i < j)
{
swap_elements(arr[i++], arr[j--]);
}
}
//------------------------------------------------------binary_search_pos
template<class Array, class Value, class Less>
unsigned binary_search_pos(const Array& arr, const Value& val, Less less)
{
if(arr.size() == 0) return 0;
unsigned beg = 0;
unsigned end = arr.size() - 1;
if(less(val, arr[0])) return 0;
if(less(arr[end], val)) return end + 1;
while(end - beg > 1)
{
unsigned mid = (end + beg) >> 1;
if(less(val, arr[mid])) end = mid;
else beg = mid;
}
//if(beg <= 0 && less(val, arr[0])) return 0;
//if(end >= arr.size() - 1 && less(arr[end], val)) ++end;
return end;
}
//----------------------------------------------------------range_adaptor
template<class Array> class range_adaptor
{
public:
typedef typename Array::value_type value_type;
range_adaptor(Array& array, unsigned start, unsigned size) :
m_array(array), m_start(start), m_size(size)
{}
unsigned size() const { return m_size; }
const value_type& operator [] (unsigned i) const { return m_array[m_start + i]; }
value_type& operator [] (unsigned i) { return m_array[m_start + i]; }
const value_type& at(unsigned i) const { return m_array[m_start + i]; }
value_type& at(unsigned i) { return m_array[m_start + i]; }
value_type value_at(unsigned i) const { return m_array[m_start + i]; }
private:
Array& m_array;
unsigned m_start;
unsigned m_size;
};
//---------------------------------------------------------------int_less
inline bool int_less(int a, int b) { return a < b; }
//------------------------------------------------------------int_greater
inline bool int_greater(int a, int b) { return a > b; }
//----------------------------------------------------------unsigned_less
inline bool unsigned_less(unsigned a, unsigned b) { return a < b; }
//-------------------------------------------------------unsigned_greater
inline bool unsigned_greater(unsigned a, unsigned b) { return a > b; }
}
#endif
+3 -3
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -57,7 +57,7 @@ namespace agg
void tail() { m_tail_flag = true; }
void no_tail() { m_tail_flag = false; }
void rewind(unsigned id);
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
+239 -25
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -16,20 +16,201 @@
#ifndef AGG_BASICS_INCLUDED
#define AGG_BASICS_INCLUDED
#include <math.h>
#include "agg_config.h"
//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR
#ifdef AGG_CUSTOM_ALLOCATOR
#include "agg_allocator.h"
#else
namespace agg
{
// The policy of all AGG containers and memory allocation strategy
// in general is that no allocated data requires explicit construction.
// It means that the allocator can be really simple; you can even
// replace new/delete to malloc/free. The constructors and destructors
// won't be called in this case, however everything will remain working.
// The second argument of deallocate() is the size of the allocated
// block. You can use this information if you wish.
//------------------------------------------------------------pod_allocator
template<class T> struct pod_allocator
{
static T* allocate(unsigned num) { return new T [num]; }
static void deallocate(T* ptr, unsigned) { delete [] ptr; }
};
// Single object allocator. It's also can be replaced with your custom
// allocator. The difference is that it can only allocate a single
// object and the constructor and destructor must be called.
// In AGG there is no need to allocate an array of objects with
// calling their constructors (only single ones). So that, if you
// replace these new/delete to malloc/free make sure that the in-place
// new is called and take care of calling the destructor too.
//------------------------------------------------------------obj_allocator
template<class T> struct obj_allocator
{
static T* allocate() { return new T; }
static void deallocate(T* ptr) { delete ptr; }
};
}
#endif
//-------------------------------------------------------- Default basic types
//
// If the compiler has different capacity of the basic types you can redefine
// them via the compiler command line or by generating agg_config.h that is
// empty by default.
//
#ifndef AGG_INT8
#define AGG_INT8 signed char
#endif
#ifndef AGG_INT8U
#define AGG_INT8U unsigned char
#endif
#ifndef AGG_INT16
#define AGG_INT16 short
#endif
#ifndef AGG_INT16U
#define AGG_INT16U unsigned short
#endif
#ifndef AGG_INT32
#define AGG_INT32 int
#endif
#ifndef AGG_INT32U
#define AGG_INT32U unsigned
#endif
#ifndef AGG_INT64
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define AGG_INT64 signed __int64
#else
#define AGG_INT64 signed long long
#endif
#endif
#ifndef AGG_INT64U
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define AGG_INT64U unsigned __int64
#else
#define AGG_INT64U unsigned long long
#endif
#endif
//------------------------------------------------ Some fixes for MS Visual C++
#if defined(_MSC_VER)
#pragma warning(disable:4786) // Identifier was truncated...
#endif
#if defined(_MSC_VER)
#define AGG_INLINE __forceinline
#else
#define AGG_INLINE inline
#endif
namespace agg
{
//-------------------------------------------------------------------------
typedef signed char int8; //----int8
typedef unsigned char int8u; //----int8u
typedef signed short int16; //----int16
typedef unsigned short int16u; //----int16u
typedef signed int int32; //----int32
typedef unsigned int int32u; //----int32u
typedef AGG_INT8 int8; //----int8
typedef AGG_INT8U int8u; //----int8u
typedef AGG_INT16 int16; //----int16
typedef AGG_INT16U int16u; //----int16u
typedef AGG_INT32 int32; //----int32
typedef AGG_INT32U int32u; //----int32u
typedef AGG_INT64 int64; //----int64
typedef AGG_INT64U int64u; //----int64u
#if defined(AGG_FISTP)
#pragma warning(push)
#pragma warning(disable : 4035) //Disable warning "no return value"
AGG_INLINE int iround(double v) //-------iround
{
int t;
__asm fld qword ptr [v]
__asm fistp dword ptr [t]
__asm mov eax, dword ptr [t]
}
AGG_INLINE unsigned uround(double v) //-------uround
{
unsigned t;
__asm fld qword ptr [v]
__asm fistp dword ptr [t]
__asm mov eax, dword ptr [t]
}
#pragma warning(pop)
AGG_INLINE unsigned ufloor(double v) //-------ufloor
{
return unsigned(floor(v));
}
AGG_INLINE unsigned uceil(double v) //--------uceil
{
return unsigned(ceil(v));
}
#elif defined(AGG_QIFIST)
AGG_INLINE int iround(double v)
{
return int(v);
}
AGG_INLINE int uround(double v)
{
return unsigned(v);
}
AGG_INLINE unsigned ufloor(double v)
{
return unsigned(floor(v));
}
AGG_INLINE unsigned uceil(double v)
{
return unsigned(ceil(v));
}
#else
AGG_INLINE int iround(double v)
{
return int((v < 0.0) ? v - 0.5 : v + 0.5);
}
AGG_INLINE int uround(double v)
{
return unsigned(v + 0.5);
}
AGG_INLINE unsigned ufloor(double v)
{
return unsigned(v);
}
AGG_INLINE unsigned uceil(double v)
{
return unsigned(ceil(v));
}
#endif
//---------------------------------------------------------------saturation
template<int Limit> struct saturation
{
AGG_INLINE static int iround(double v)
{
if(v < double(-Limit)) return -Limit;
if(v > double( Limit)) return Limit;
return agg::iround(v);
}
};
//------------------------------------------------------------------mul_one
template<unsigned Shift> struct mul_one
{
AGG_INLINE static unsigned mul(unsigned a, unsigned b)
{
register unsigned q = a * b + (1 << (Shift-1));
return (q + (q >> Shift)) >> Shift;
}
};
//-------------------------------------------------------------------------
typedef unsigned char cover_type; //----cover_type
enum
enum cover_scale_e
{
cover_shift = 8, //----cover_shift
cover_size = 1 << cover_shift, //----cover_size
@@ -38,6 +219,25 @@ namespace agg
cover_full = cover_mask //----cover_full
};
//----------------------------------------------------poly_subpixel_scale_e
// These constants determine the subpixel accuracy, to be more precise,
// the number of bits of the fractional part of the coordinates.
// The possible coordinate capacity in bits can be calculated by formula:
// sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
// 8-bits fractional part the capacity is 24 bits.
enum poly_subpixel_scale_e
{
poly_subpixel_shift = 8, //----poly_subpixel_shift
poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale
poly_subpixel_mask = poly_subpixel_scale-1, //----poly_subpixel_mask
};
//----------------------------------------------------------filling_rule_e
enum filling_rule_e
{
fill_non_zero,
fill_even_odd
};
//-----------------------------------------------------------------------pi
const double pi = 3.14159265358979323846;
@@ -121,7 +321,8 @@ namespace agg
return r;
}
typedef rect_base<int> rect; //----rect
typedef rect_base<int> rect_i; //----rect_i
typedef rect_base<float> rect_f; //----rect_f
typedef rect_base<double> rect_d; //----rect_d
//---------------------------------------------------------path_commands_e
@@ -132,7 +333,10 @@ namespace agg
path_cmd_line_to = 2, //----path_cmd_line_to
path_cmd_curve3 = 3, //----path_cmd_curve3
path_cmd_curve4 = 4, //----path_cmd_curve4
path_cmd_end_poly = 6, //----path_cmd_end_poly
path_cmd_curveN = 5, //----path_cmd_curveN
path_cmd_catrom = 6, //----path_cmd_catrom
path_cmd_ubspline = 7, //----path_cmd_ubspline
path_cmd_end_poly = 0x0F, //----path_cmd_end_poly
path_cmd_mask = 0x0F //----path_cmd_mask
};
@@ -152,6 +356,12 @@ namespace agg
return c >= path_cmd_move_to && c < path_cmd_end_poly;
}
//--------------------------------------------------------------is_drawing
inline bool is_drawing(unsigned c)
{
return c >= path_cmd_line_to && c < path_cmd_end_poly;
}
//-----------------------------------------------------------------is_stop
inline bool is_stop(unsigned c)
{
@@ -255,26 +465,30 @@ namespace agg
return clear_orientation(c) | o;
}
//--------------------------------------------------------------point_type
struct point_type
//--------------------------------------------------------------point_base
template<class T> struct point_base
{
double x, y;
point_type() {}
point_type(double x_, double y_) : x(x_), y(y_) {}
typedef T value_type;
T x,y;
point_base() {}
point_base(T x_, T y_) : x(x_), y(y_) {}
};
typedef point_base<int> point_i; //-----point_i
typedef point_base<float> point_f; //-----point_f
typedef point_base<double> point_d; //-----point_d
//-------------------------------------------------------------vertex_type
struct vertex_type
//-------------------------------------------------------------vertex_base
template<class T> struct vertex_base
{
double x, y;
typedef T value_type;
T x,y;
unsigned cmd;
vertex_type() {}
vertex_type(double x_, double y_, unsigned cmd_) :
x(x_), y(y_), cmd(cmd_) {}
vertex_base() {}
vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {}
};
typedef vertex_base<int> vertex_i; //-----vertex_i
typedef vertex_base<float> vertex_f; //-----vertex_f
typedef vertex_base<double> vertex_d; //-----vertex_d
}
+5 -4
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -40,7 +40,7 @@ namespace agg
{
public:
//--------------------------------------------------------------------
bezier_arc() : m_vertex(26) {}
bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {}
bezier_arc(double x, double y,
double rx, double ry,
double start_angle,
@@ -68,7 +68,7 @@ namespace agg
*x = m_vertices[m_vertex];
*y = m_vertices[m_vertex + 1];
m_vertex += 2;
return (m_vertex == 2) ? path_cmd_move_to : path_cmd_curve4;
return (m_vertex == 2) ? path_cmd_move_to : m_cmd;
}
// Supplemantary functions. num_vertices() actually returns doubled
@@ -82,6 +82,7 @@ namespace agg
unsigned m_vertex;
unsigned m_num_vertices;
double m_vertices[26];
unsigned m_cmd;
};
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+9 -10
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -20,7 +20,7 @@
#ifndef AGG_BSPLINE_INCLUDED
#define AGG_BSPLINE_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
namespace agg
{
@@ -40,7 +40,6 @@ namespace agg
class bspline
{
public:
~bspline();
bspline();
bspline(int num);
bspline(int num, const double* x, const double* y);
@@ -63,12 +62,12 @@ namespace agg
double extrapolation_right(double x) const;
double interpolation(double x, int i) const;
int m_max;
int m_num;
double* m_x;
double* m_y;
double* m_am;
mutable int m_last_idx;
int m_max;
int m_num;
double* m_x;
double* m_y;
pod_array<double> m_am;
mutable int m_last_idx;
};
+127 -3
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -24,6 +24,17 @@
namespace agg
{
//------------------------------------------------------------------------
enum clipping_flags_e
{
clipping_flags_x1_clipped = 4,
clipping_flags_x2_clipped = 1,
clipping_flags_y1_clipped = 8,
clipping_flags_y2_clipped = 2,
clipping_flags_x_clipped = clipping_flags_x1_clipped | clipping_flags_x2_clipped,
clipping_flags_y_clipped = clipping_flags_y1_clipped | clipping_flags_y2_clipped
};
//----------------------------------------------------------clipping_flags
// Determine the clipping code of the vertex according to the
// Cyrus-Beck line clipping algorithm
@@ -51,6 +62,20 @@ namespace agg
((y < clip_box.y1) << 3);
}
//--------------------------------------------------------clipping_flags_x
template<class T>
inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box)
{
return (x > clip_box.x2) | ((x < clip_box.x1) << 2);
}
//--------------------------------------------------------clipping_flags_y
template<class T>
inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box)
{
return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3);
}
//-------------------------------------------------------clip_liang_barsky
@@ -202,8 +227,107 @@ namespace agg
}
return np;
}
//----------------------------------------------------------------------------
template<class T>
bool clip_move_point(T x1, T y1, T x2, T y2,
const rect_base<T>& clip_box,
T* x, T* y, unsigned flags)
{
T bound;
if(flags & clipping_flags_x_clipped)
{
if(x1 == x2)
{
return false;
}
bound = (flags & clipping_flags_x1_clipped) ? clip_box.x1 : clip_box.x2;
*y = (T)(double(bound - x1) * (y2 - y1) / (x2 - x1) + y1);
*x = bound;
}
flags = clipping_flags_y(*y, clip_box);
if(flags & clipping_flags_y_clipped)
{
if(y1 == y2)
{
return false;
}
bound = (flags & clipping_flags_y1_clipped) ? clip_box.y1 : clip_box.y2;
*x = (T)(double(bound - y1) * (x2 - x1) / (y2 - y1) + x1);
*y = bound;
}
return true;
}
//-------------------------------------------------------clip_line_segment
// Returns: ret >= 4 - Fully clipped
// (ret & 1) != 0 - First point has been moved
// (ret & 2) != 0 - Second point has been moved
//
template<class T>
unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2,
const rect_base<T>& clip_box)
{
unsigned f1 = clipping_flags(*x1, *y1, clip_box);
unsigned f2 = clipping_flags(*x2, *y2, clip_box);
unsigned ret = 0;
if((f2 | f1) == 0)
{
// Fully visible
return 0;
}
if((f1 & clipping_flags_x_clipped) != 0 &&
(f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped))
{
// Fully clipped
return 4;
}
if((f1 & clipping_flags_y_clipped) != 0 &&
(f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped))
{
// Fully clipped
return 4;
}
T tx1 = *x1;
T ty1 = *y1;
T tx2 = *x2;
T ty2 = *y2;
if(f1)
{
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1))
{
return 4;
}
if(*x1 == *x2 && *y1 == *y2)
{
return 4;
}
ret |= 1;
}
if(f2)
{
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2))
{
return 4;
}
if(*x1 == *x2 && *y1 == *y2)
{
return 4;
}
ret |= 2;
}
return ret;
}
}
#endif
+414
View File
@@ -0,0 +1,414 @@
//----------------------------------------------------------------------------
// 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for high precision colors has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
//
// color types gray8, gray16
//
//----------------------------------------------------------------------------
#ifndef AGG_COLOR_GRAY_INCLUDED
#define AGG_COLOR_GRAY_INCLUDED
#include "agg_basics.h"
#include "agg_color_rgba.h"
namespace agg
{
//===================================================================gray8
struct gray8
{
typedef int8u value_type;
typedef int32u calc_type;
typedef int32 long_type;
enum base_scale_e
{
base_shift = 8,
base_scale = 1 << base_shift,
base_mask = base_scale - 1
};
typedef gray8 self_type;
value_type v;
value_type a;
//--------------------------------------------------------------------
gray8() {}
//--------------------------------------------------------------------
gray8(unsigned v_, unsigned a_=base_mask) :
v(int8u(v_)), a(int8u(a_)) {}
//--------------------------------------------------------------------
gray8(const self_type& c, unsigned a_) :
v(c.v), a(value_type(a_)) {}
//--------------------------------------------------------------------
gray8(const rgba& c) :
v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
a((value_type)uround(c.a * double(base_mask))) {}
//--------------------------------------------------------------------
gray8(const rgba& c, double a_) :
v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
a((value_type)uround(a_ * double(base_mask))) {}
//--------------------------------------------------------------------
gray8(const rgba8& c) :
v((c.r*77 + c.g*150 + c.b*29) >> 8),
a(c.a) {}
//--------------------------------------------------------------------
gray8(const rgba8& c, unsigned a_) :
v((c.r*77 + c.g*150 + c.b*29) >> 8),
a(a_) {}
//--------------------------------------------------------------------
void clear()
{
v = a = 0;
}
//--------------------------------------------------------------------
const self_type& transparent()
{
a = 0;
return *this;
}
//--------------------------------------------------------------------
void opacity(double a_)
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
a = (value_type)uround(a_ * double(base_mask));
}
//--------------------------------------------------------------------
double opacity() const
{
return double(a) / double(base_mask);
}
//--------------------------------------------------------------------
const self_type& premultiply()
{
if(a == base_mask) return *this;
if(a == 0)
{
v = 0;
return *this;
}
v = value_type((calc_type(v) * a) >> base_shift);
return *this;
}
//--------------------------------------------------------------------
const self_type& premultiply(unsigned a_)
{
if(a == base_mask && a_ >= base_mask) return *this;
if(a == 0 || a_ == 0)
{
v = a = 0;
return *this;
}
calc_type v_ = (calc_type(v) * a_) / a;
v = value_type((v_ > a_) ? a_ : v_);
a = value_type(a_);
return *this;
}
//--------------------------------------------------------------------
const self_type& demultiply()
{
if(a == base_mask) return *this;
if(a == 0)
{
v = 0;
return *this;
}
calc_type v_ = (calc_type(v) * base_mask) / a;
v = value_type((v_ > base_mask) ? base_mask : v_);
return *this;
}
//--------------------------------------------------------------------
self_type gradient(self_type c, double k) const
{
self_type ret;
calc_type ik = uround(k * base_scale);
ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
return ret;
}
//--------------------------------------------------------------------
AGG_INLINE void add(const self_type& c, unsigned cover)
{
calc_type cv, ca;
if(cover == cover_mask)
{
if(c.a == base_mask)
{
*this = c;
}
else
{
cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
}
}
else
{
cv = v + ((c.v * cover + cover_mask/2) >> cover_shift);
ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
}
}
//--------------------------------------------------------------------
static self_type no_color() { return self_type(0,0); }
};
//-------------------------------------------------------------gray8_pre
inline gray8 gray8_pre(unsigned v, unsigned a = gray8::base_mask)
{
return gray8(v,a).premultiply();
}
inline gray8 gray8_pre(const gray8& c, unsigned a)
{
return gray8(c,a).premultiply();
}
inline gray8 gray8_pre(const rgba& c)
{
return gray8(c).premultiply();
}
inline gray8 gray8_pre(const rgba& c, double a)
{
return gray8(c,a).premultiply();
}
inline gray8 gray8_pre(const rgba8& c)
{
return gray8(c).premultiply();
}
inline gray8 gray8_pre(const rgba8& c, unsigned a)
{
return gray8(c,a).premultiply();
}
//==================================================================gray16
struct gray16
{
typedef int16u value_type;
typedef int32u calc_type;
typedef int64 long_type;
enum base_scale_e
{
base_shift = 16,
base_scale = 1 << base_shift,
base_mask = base_scale - 1
};
typedef gray16 self_type;
value_type v;
value_type a;
//--------------------------------------------------------------------
gray16() {}
//--------------------------------------------------------------------
gray16(unsigned v_, unsigned a_=base_mask) :
v(int16u(v_)), a(int16u(a_)) {}
//--------------------------------------------------------------------
gray16(const self_type& c, unsigned a_) :
v(c.v), a(value_type(a_)) {}
//--------------------------------------------------------------------
gray16(const rgba& c) :
v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
a((value_type)uround(c.a * double(base_mask))) {}
//--------------------------------------------------------------------
gray16(const rgba& c, double a_) :
v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
a((value_type)uround(a_ * double(base_mask))) {}
//--------------------------------------------------------------------
gray16(const rgba8& c) :
v(c.r*77 + c.g*150 + c.b*29),
a((value_type(c.a) << 8) | c.a) {}
//--------------------------------------------------------------------
gray16(const rgba8& c, unsigned a_) :
v(c.r*77 + c.g*150 + c.b*29),
a((value_type(a_) << 8) | c.a) {}
//--------------------------------------------------------------------
void clear()
{
v = a = 0;
}
//--------------------------------------------------------------------
const self_type& transparent()
{
a = 0;
return *this;
}
//--------------------------------------------------------------------
void opacity(double a_)
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
a = (value_type)uround(a_ * double(base_mask));
}
//--------------------------------------------------------------------
double opacity() const
{
return double(a) / double(base_mask);
}
//--------------------------------------------------------------------
const self_type& premultiply()
{
if(a == base_mask) return *this;
if(a == 0)
{
v = 0;
return *this;
}
v = value_type((calc_type(v) * a) >> base_shift);
return *this;
}
//--------------------------------------------------------------------
const self_type& premultiply(unsigned a_)
{
if(a == base_mask && a_ >= base_mask) return *this;
if(a == 0 || a_ == 0)
{
v = a = 0;
return *this;
}
calc_type v_ = (calc_type(v) * a_) / a;
v = value_type((v_ > a_) ? a_ : v_);
a = value_type(a_);
return *this;
}
//--------------------------------------------------------------------
const self_type& demultiply()
{
if(a == base_mask) return *this;
if(a == 0)
{
v = 0;
return *this;
}
calc_type v_ = (calc_type(v) * base_mask) / a;
v = value_type((v_ > base_mask) ? base_mask : v_);
return *this;
}
//--------------------------------------------------------------------
self_type gradient(self_type c, double k) const
{
self_type ret;
calc_type ik = uround(k * base_scale);
ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
return ret;
}
//--------------------------------------------------------------------
AGG_INLINE void add(const self_type& c, unsigned cover)
{
calc_type cv, ca;
if(cover == cover_mask)
{
if(c.a == base_mask)
{
*this = c;
}
else
{
cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
}
}
else
{
cv = v + ((c.v * cover + cover_mask/2) >> cover_shift);
ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
}
}
//--------------------------------------------------------------------
static self_type no_color() { return self_type(0,0); }
};
//------------------------------------------------------------gray16_pre
inline gray16 gray16_pre(unsigned v, unsigned a = gray16::base_mask)
{
return gray16(v,a).premultiply();
}
inline gray16 gray16_pre(const gray16& c, unsigned a)
{
return gray16(c,a).premultiply();
}
inline gray16 gray16_pre(const rgba& c)
{
return gray16(c).premultiply();
}
inline gray16 gray16_pre(const rgba& c, double a)
{
return gray16(c,a).premultiply();
}
inline gray16 gray16_pre(const rgba8& c)
{
return gray16(c).premultiply();
}
inline gray16 gray16_pre(const rgba8& c, unsigned a)
{
return gray16(c,a).premultiply();
}
}
#endif
+518 -55
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -8,14 +8,18 @@
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
//
// Adaptation for high precision colors has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
// Contact: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// color type rgba
//
//----------------------------------------------------------------------------
#ifndef AGG_COLOR_RGBA_INCLUDED
#define AGG_COLOR_RGBA_INCLUDED
@@ -25,11 +29,19 @@
namespace agg
{
// Supported byte orders for RGB and RGBA pixel formats
//=======================================================================
struct order_rgb { enum rgb_e { R=0, G=1, B=2, rgb_tag }; }; //----order_rgb
struct order_bgr { enum bgr_e { B=0, G=1, R=2, rgb_tag }; }; //----order_bgr
struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, rgba_tag }; }; //----order_rgba
struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, rgba_tag }; }; //----order_argb
struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, rgba_tag }; }; //----order_abgr
struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, rgba_tag }; }; //----order_bgra
//====================================================================rgba
struct rgba
{
typedef double alpha_type;
enum premul { pre };
typedef double value_type;
double r;
double g;
@@ -43,28 +55,9 @@ namespace agg
rgba(double r_, double g_, double b_, double a_=1.0) :
r(r_), g(g_), b(b_), a(a_) {}
//--------------------------------------------------------------------
rgba(premul, double r_, double g_, double b_, double a_=1.0) :
r(r_), g(g_), b(b_), a(a_)
{
premultiply();
}
//--------------------------------------------------------------------
rgba(premul, const rgba& c) : r(c.r), g(c.g), b(c.b), a(c.a)
{
premultiply();
}
//--------------------------------------------------------------------
rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {}
//--------------------------------------------------------------------
rgba(premul, const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_)
{
premultiply();
}
//--------------------------------------------------------------------
void clear()
{
@@ -78,13 +71,6 @@ namespace agg
return *this;
}
//--------------------------------------------------------------------
const rgba& transparent(premul)
{
clear();
return *this;
}
//--------------------------------------------------------------------
const rgba& opacity(double a_)
{
@@ -94,15 +80,6 @@ namespace agg
return *this;
}
//--------------------------------------------------------------------
const rgba& opacity(premul, double a_)
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
premultiply(a_);
return *this;
}
//--------------------------------------------------------------------
double opacity() const
{
@@ -121,7 +98,7 @@ namespace agg
//--------------------------------------------------------------------
const rgba& premultiply(double a_)
{
if(a == 0.0 || a_ == 0.0)
if(a <= 0.0 || a_ <= 0.0)
{
r = g = b = a = 0.0;
return *this;
@@ -168,33 +145,27 @@ namespace agg
static rgba from_wavelength(double wl, double gamma = 1.0);
//--------------------------------------------------------------------
rgba(double wavelen, double gamma=1.0)
explicit rgba(double wavelen, double gamma=1.0)
{
*this = from_wavelength(wavelen, gamma);
}
};
//------------------------------------------------------------------------
//----------------------------------------------------------------rgba_pre
inline rgba rgba_pre(double r, double g, double b, double a=1.0)
{
return rgba(rgba::pre, r, g, b, a);
return rgba(r, g, b, a).premultiply();
}
//--------------------------------------------------------------------
inline rgba rgba_pre(const rgba& c)
{
return rgba(rgba::pre, c);
return rgba(c).premultiply();
}
//--------------------------------------------------------------------
inline rgba rgba_pre(const rgba& c, double a)
{
return rgba(rgba::pre, c, a);
return rgba(c, a).premultiply();
}
//------------------------------------------------------------------------
inline rgba rgba::from_wavelength(double wl, double gamma)
{
@@ -247,7 +218,499 @@ namespace agg
//===================================================================rgba8
struct rgba8
{
typedef int8u value_type;
typedef int32u calc_type;
typedef int32 long_type;
enum base_scale_e
{
base_shift = 8,
base_scale = 1 << base_shift,
base_mask = base_scale - 1
};
typedef rgba8 self_type;
value_type r;
value_type g;
value_type b;
value_type a;
//--------------------------------------------------------------------
rgba8() {}
//--------------------------------------------------------------------
rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
r(value_type(r_)),
g(value_type(g_)),
b(value_type(b_)),
a(value_type(a_)) {}
//--------------------------------------------------------------------
rgba8(const rgba& c, double a_) :
r((value_type)uround(c.r * double(base_mask))),
g((value_type)uround(c.g * double(base_mask))),
b((value_type)uround(c.b * double(base_mask))),
a((value_type)uround(a_ * double(base_mask))) {}
//--------------------------------------------------------------------
rgba8(const self_type& c, unsigned a_) :
r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
//--------------------------------------------------------------------
rgba8(const rgba& c) :
r((value_type)uround(c.r * double(base_mask))),
g((value_type)uround(c.g * double(base_mask))),
b((value_type)uround(c.b * double(base_mask))),
a((value_type)uround(c.a * double(base_mask))) {}
//--------------------------------------------------------------------
void clear()
{
r = g = b = a = 0;
}
//--------------------------------------------------------------------
const self_type& transparent()
{
a = 0;
return *this;
}
//--------------------------------------------------------------------
const self_type& opacity(double a_)
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
a = (value_type)uround(a_ * double(base_mask));
return *this;
}
//--------------------------------------------------------------------
double opacity() const
{
return double(a) / double(base_mask);
}
//--------------------------------------------------------------------
AGG_INLINE const self_type& premultiply()
{
if(a == base_mask) return *this;
if(a == 0)
{
r = g = b = 0;
return *this;
}
r = value_type((calc_type(r) * a) >> base_shift);
g = value_type((calc_type(g) * a) >> base_shift);
b = value_type((calc_type(b) * a) >> base_shift);
return *this;
}
//--------------------------------------------------------------------
AGG_INLINE const self_type& premultiply(unsigned a_)
{
if(a == base_mask && a_ >= base_mask) return *this;
if(a == 0 || a_ == 0)
{
r = g = b = a = 0;
return *this;
}
calc_type r_ = (calc_type(r) * a_) / a;
calc_type g_ = (calc_type(g) * a_) / a;
calc_type b_ = (calc_type(b) * a_) / a;
r = value_type((r_ > a_) ? a_ : r_);
g = value_type((g_ > a_) ? a_ : g_);
b = value_type((b_ > a_) ? a_ : b_);
a = value_type(a_);
return *this;
}
//--------------------------------------------------------------------
AGG_INLINE const self_type& demultiply()
{
if(a == base_mask) return *this;
if(a == 0)
{
r = g = b = 0;
return *this;
}
calc_type r_ = (calc_type(r) * base_mask) / a;
calc_type g_ = (calc_type(g) * base_mask) / a;
calc_type b_ = (calc_type(b) * base_mask) / a;
r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
return *this;
}
//--------------------------------------------------------------------
AGG_INLINE self_type gradient(const self_type& c, double k) const
{
self_type ret;
calc_type ik = uround(k * base_scale);
ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
return ret;
}
//--------------------------------------------------------------------
AGG_INLINE void add(const self_type& c, unsigned cover)
{
calc_type cr, cg, cb, ca;
if(cover == cover_mask)
{
if(c.a == base_mask)
{
*this = c;
}
else
{
cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
}
}
else
{
cr = r + ((c.r * cover + cover_mask/2) >> cover_shift);
cg = g + ((c.g * cover + cover_mask/2) >> cover_shift);
cb = b + ((c.b * cover + cover_mask/2) >> cover_shift);
ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
}
}
//--------------------------------------------------------------------
template<class GammaLUT>
AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
{
r = gamma.dir(r);
g = gamma.dir(g);
b = gamma.dir(b);
}
//--------------------------------------------------------------------
template<class GammaLUT>
AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
{
r = gamma.inv(r);
g = gamma.inv(g);
b = gamma.inv(b);
}
//--------------------------------------------------------------------
static self_type no_color() { return self_type(0,0,0,0); }
//--------------------------------------------------------------------
static self_type from_wavelength(double wl, double gamma = 1.0)
{
return self_type(rgba::from_wavelength(wl, gamma));
}
};
//-------------------------------------------------------------rgba8_pre
inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b,
unsigned a = rgba8::base_mask)
{
return rgba8(r,g,b,a).premultiply();
}
inline rgba8 rgba8_pre(const rgba8& c)
{
return rgba8(c).premultiply();
}
inline rgba8 rgba8_pre(const rgba8& c, unsigned a)
{
return rgba8(c,a).premultiply();
}
inline rgba8 rgba8_pre(const rgba& c)
{
return rgba8(c).premultiply();
}
inline rgba8 rgba8_pre(const rgba& c, double a)
{
return rgba8(c,a).premultiply();
}
//-----------------------------------------------------------rgb8_packed
inline rgba8 rgb8_packed(unsigned v)
{
return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
}
//-----------------------------------------------------------bgr8_packed
inline rgba8 bgr8_packed(unsigned v)
{
return rgba8(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF);
}
//----------------------------------------------------------argb8_packed
inline rgba8 argb8_packed(unsigned v)
{
return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF, v >> 24);
}
//=================================================================rgba16
struct rgba16
{
typedef int16u value_type;
typedef int32u calc_type;
typedef int64 long_type;
enum base_scale_e
{
base_shift = 16,
base_scale = 1 << base_shift,
base_mask = base_scale - 1
};
typedef rgba16 self_type;
value_type r;
value_type g;
value_type b;
value_type a;
//--------------------------------------------------------------------
rgba16() {}
//--------------------------------------------------------------------
rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
r(value_type(r_)),
g(value_type(g_)),
b(value_type(b_)),
a(value_type(a_)) {}
//--------------------------------------------------------------------
rgba16(const self_type& c, unsigned a_) :
r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
//--------------------------------------------------------------------
rgba16(const rgba& c) :
r((value_type)uround(c.r * double(base_mask))),
g((value_type)uround(c.g * double(base_mask))),
b((value_type)uround(c.b * double(base_mask))),
a((value_type)uround(c.a * double(base_mask))) {}
//--------------------------------------------------------------------
rgba16(const rgba& c, double a_) :
r((value_type)uround(c.r * double(base_mask))),
g((value_type)uround(c.g * double(base_mask))),
b((value_type)uround(c.b * double(base_mask))),
a((value_type)uround(a_ * double(base_mask))) {}
//--------------------------------------------------------------------
rgba16(const rgba8& c) :
r(value_type((value_type(c.r) << 8) | c.r)),
g(value_type((value_type(c.g) << 8) | c.g)),
b(value_type((value_type(c.b) << 8) | c.b)),
a(value_type((value_type(c.a) << 8) | c.a)) {}
//--------------------------------------------------------------------
rgba16(const rgba8& c, unsigned a_) :
r(value_type((value_type(c.r) << 8) | c.r)),
g(value_type((value_type(c.g) << 8) | c.g)),
b(value_type((value_type(c.b) << 8) | c.b)),
a(value_type(( a_ << 8) | c.a)) {}
//--------------------------------------------------------------------
void clear()
{
r = g = b = a = 0;
}
//--------------------------------------------------------------------
const self_type& transparent()
{
a = 0;
return *this;
}
//--------------------------------------------------------------------
AGG_INLINE const self_type& opacity(double a_)
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
a = (value_type)uround(a_ * double(base_mask));
return *this;
}
//--------------------------------------------------------------------
double opacity() const
{
return double(a) / double(base_mask);
}
//--------------------------------------------------------------------
AGG_INLINE const self_type& premultiply()
{
if(a == base_mask) return *this;
if(a == 0)
{
r = g = b = 0;
return *this;
}
r = value_type((calc_type(r) * a) >> base_shift);
g = value_type((calc_type(g) * a) >> base_shift);
b = value_type((calc_type(b) * a) >> base_shift);
return *this;
}
//--------------------------------------------------------------------
AGG_INLINE const self_type& premultiply(unsigned a_)
{
if(a == base_mask && a_ >= base_mask) return *this;
if(a == 0 || a_ == 0)
{
r = g = b = a = 0;
return *this;
}
calc_type r_ = (calc_type(r) * a_) / a;
calc_type g_ = (calc_type(g) * a_) / a;
calc_type b_ = (calc_type(b) * a_) / a;
r = value_type((r_ > a_) ? a_ : r_);
g = value_type((g_ > a_) ? a_ : g_);
b = value_type((b_ > a_) ? a_ : b_);
a = value_type(a_);
return *this;
}
//--------------------------------------------------------------------
AGG_INLINE const self_type& demultiply()
{
if(a == base_mask) return *this;
if(a == 0)
{
r = g = b = 0;
return *this;
}
calc_type r_ = (calc_type(r) * base_mask) / a;
calc_type g_ = (calc_type(g) * base_mask) / a;
calc_type b_ = (calc_type(b) * base_mask) / a;
r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
return *this;
}
//--------------------------------------------------------------------
AGG_INLINE self_type gradient(const self_type& c, double k) const
{
self_type ret;
calc_type ik = uround(k * base_scale);
ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
return ret;
}
//--------------------------------------------------------------------
AGG_INLINE void add(const self_type& c, unsigned cover)
{
calc_type cr, cg, cb, ca;
if(cover == cover_mask)
{
if(c.a == base_mask)
{
*this = c;
}
else
{
cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
}
}
else
{
cr = r + ((c.r * cover + cover_mask) >> cover_shift);
cg = g + ((c.g * cover + cover_mask) >> cover_shift);
cb = b + ((c.b * cover + cover_mask) >> cover_shift);
ca = a + ((c.a * cover + cover_mask) >> cover_shift);
r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
}
}
//--------------------------------------------------------------------
template<class GammaLUT>
AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
{
r = gamma.dir(r);
g = gamma.dir(g);
b = gamma.dir(b);
}
//--------------------------------------------------------------------
template<class GammaLUT>
AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
{
r = gamma.inv(r);
g = gamma.inv(g);
b = gamma.inv(b);
}
//--------------------------------------------------------------------
static self_type no_color() { return self_type(0,0,0,0); }
//--------------------------------------------------------------------
static self_type from_wavelength(double wl, double gamma = 1.0)
{
return self_type(rgba::from_wavelength(wl, gamma));
}
};
//--------------------------------------------------------------rgba16_pre
inline rgba16 rgba16_pre(unsigned r, unsigned g, unsigned b,
unsigned a = rgba16::base_mask)
{
return rgba16(r,g,b,a).premultiply();
}
inline rgba16 rgba16_pre(const rgba16& c, unsigned a)
{
return rgba16(c,a).premultiply();
}
inline rgba16 rgba16_pre(const rgba& c)
{
return rgba16(c).premultiply();
}
inline rgba16 rgba16_pre(const rgba& c, double a)
{
return rgba16(c,a).premultiply();
}
inline rgba16 rgba16_pre(const rgba8& c)
{
return rgba16(c).premultiply();
}
inline rgba16 rgba16_pre(const rgba8& c, unsigned a)
{
return rgba16(c,a).premultiply();
}
}
#endif
-257
View File
@@ -1,257 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// color type rgba8
//
//----------------------------------------------------------------------------
#ifndef AGG_COLOR_RGBA8_INCLUDED
#define AGG_COLOR_RGBA8_INCLUDED
#include "agg_basics.h"
#include "agg_color_rgba.h"
namespace agg
{
// Supported byte orders for RGB and RGBA pixel formats
//=======================================================================
struct order_rgb24 { enum { R=0, G=1, B=2, rgb24_tag }; }; //----order_rgb24
struct order_bgr24 { enum { B=0, G=1, R=2, rgb24_tag }; }; //----order_bgr24
struct order_rgba32 { enum { R=0, G=1, B=2, A=3, rgba32_tag }; }; //----order_rgba32
struct order_argb32 { enum { A=0, R=1, G=2, B=3, rgba32_tag }; }; //----order_argb32
struct order_abgr32 { enum { A=0, B=1, G=2, R=3, rgba32_tag }; }; //----order_abgr32
struct order_bgra32 { enum { B=0, G=1, R=2, A=3, rgba32_tag }; }; //----order_bgra32
//==================================================================rgba8
struct rgba8
{
typedef int8u alpha_type;
enum order { rgb, bgr };
enum premul { pre };
int8u r;
int8u g;
int8u b;
int8u a;
//--------------------------------------------------------------------
rgba8() {}
//--------------------------------------------------------------------
rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=255) :
r(int8u(r_)), g(int8u(g_)), b(int8u(b_)), a(int8u(a_)) {}
//--------------------------------------------------------------------
rgba8(premul, unsigned r_, unsigned g_, unsigned b_, unsigned a_=255) :
r(int8u(r_)), g(int8u(g_)), b(int8u(b_)), a(int8u(a_))
{
premultiply();
}
//--------------------------------------------------------------------
rgba8(const rgba& c) :
r(int8u(c.r * 255.0 + 0.5)),
g(int8u(c.g * 255.0 + 0.5)),
b(int8u(c.b * 255.0 + 0.5)),
a(int8u(c.a * 255.0 + 0.5)) {}
//--------------------------------------------------------------------
rgba8(premul, const rgba8& c) :
r(int8u(c.r)), g(int8u(c.g)), b(int8u(c.b)), a(int8u(c.a))
{
premultiply();
}
//--------------------------------------------------------------------
rgba8(const rgba8& c, unsigned a_) :
r(int8u(c.r)), g(int8u(c.g)), b(int8u(c.b)), a(int8u(a_)) {}
//--------------------------------------------------------------------
rgba8(premul, const rgba8& c, unsigned a_) :
r(int8u(c.r)), g(int8u(c.g)), b(int8u(c.b)), a(int8u(a_))
{
premultiply();
}
//--------------------------------------------------------------------
rgba8(unsigned packed, order o) :
r(int8u((o == rgb) ? ((packed >> 16) & 0xFF) : (packed & 0xFF))),
g(int8u((packed >> 8) & 0xFF)),
b(int8u((o == rgb) ? (packed & 0xFF) : ((packed >> 16) & 0xFF))),
a(255) {}
//--------------------------------------------------------------------
rgba8(premul, unsigned packed, order o) :
r(int8u((o == rgb) ? ((packed >> 16) & 0xFF) : (packed & 0xFF))),
g(int8u((packed >> 8) & 0xFF)),
b(int8u((o == rgb) ? (packed & 0xFF) : ((packed >> 16) & 0xFF))),
a(255)
{
premultiply();
}
//--------------------------------------------------------------------
void clear()
{
r = g = b = a = 0;
}
//--------------------------------------------------------------------
const rgba8& transparent()
{
a = 0;
return *this;
}
//--------------------------------------------------------------------
const rgba8& transparent(premul)
{
clear();
return *this;
}
//--------------------------------------------------------------------
const rgba8& opacity(double a_)
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
a = int8u(a_ * 255.0 + 0.5);
return *this;
}
//--------------------------------------------------------------------
const rgba8& opacity(premul, double a_)
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
a = int8u(a_ * 255.0 + 0.5);
premultiply(int8u(a_ * 255.0));
return *this;
}
//--------------------------------------------------------------------
double opacity() const
{
return double(a) / 255.0;
}
//--------------------------------------------------------------------
const rgba8& premultiply()
{
if(a == 255) return *this;
if(a == 0)
{
r = g = b = 0;
return *this;
}
r = (r * a) >> 8;
g = (g * a) >> 8;
b = (b * a) >> 8;
return *this;
}
//--------------------------------------------------------------------
const rgba8& premultiply(unsigned a_)
{
if(a == 255 && a_ >= 255) return *this;
if(a == 0 || a_ == 0)
{
r = g = b = a = 0;
return *this;
}
unsigned r_ = (r * a_) / a;
unsigned g_ = (g * a_) / a;
unsigned b_ = (b * a_) / a;
r = int8u((r_ > a_) ? a_ : r_);
g = int8u((g_ > a_) ? a_ : g_);
b = int8u((b_ > a_) ? a_ : b_);
a = int8u(a_);
return *this;
}
//--------------------------------------------------------------------
const rgba8& demultiply()
{
if(a == 255) return *this;
if(a == 0)
{
r = g = b = 0;
return *this;
}
unsigned r_ = (r * 255) / a;
unsigned g_ = (g * 255) / a;
unsigned b_ = (b * 255) / a;
r = (r_ > 255) ? 255 : r_;
g = (g_ > 255) ? 255 : g_;
b = (b_ > 255) ? 255 : b_;
return *this;
}
//--------------------------------------------------------------------
rgba8 gradient(rgba8 c, double k) const
{
rgba8 ret;
int ik = int(k * 256);
ret.r = int8u(int(r) + (((int(c.r) - int(r)) * ik) >> 8));
ret.g = int8u(int(g) + (((int(c.g) - int(g)) * ik) >> 8));
ret.b = int8u(int(b) + (((int(c.b) - int(b)) * ik) >> 8));
ret.a = int8u(int(a) + (((int(c.a) - int(a)) * ik) >> 8));
return ret;
}
//--------------------------------------------------------------------
static rgba8 no_color() { return rgba8(0,0,0,0); }
//--------------------------------------------------------------------
static rgba8 from_wavelength(double wl, double gamma = 1.0)
{
return rgba8(rgba::from_wavelength(wl, gamma));
}
//--------------------------------------------------------------------
rgba8(double wavelen, double gamma=1.0)
{
*this = from_wavelength(wavelen, gamma);
}
};
//------------------------------------------------------------------------
inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, unsigned a=255)
{
return rgba8(rgba8::pre, r, g, b, a);
}
//--------------------------------------------------------------------
inline rgba8 rgba8_pre(const rgba& c)
{
return rgba8(rgba8::pre, c);
}
//--------------------------------------------------------------------
inline rgba8 rgba8_pre(const rgba8& c, unsigned a)
{
return rgba8(rgba8::pre, c, a);
}
}
#endif
+26
View File
@@ -0,0 +1,26 @@
#ifndef AGG_CONFIG_INCLUDED
#define AGG_CONFIG_INCLUDED
// This file can be used to redefine the default basic types such as:
//
// AGG_INT8
// AGG_INT8U
// AGG_INT16
// AGG_INT16U
// AGG_INT32
// AGG_INT32U
// AGG_INT64
// AGG_INT64U
//
// Just replace this file with new defines if necessary.
// For example, if your compiler doesn't have a 64 bit integer type
// you can still use AGG if you define the follows:
//
// #define AGG_INT64 int
// #define AGG_INT64U unsigned
//
// It will result in overflow in 16 bit-per-component image/pattern resampling
// but it won't result any crash and the rest of the library will remain
// fully functional.
#endif
+5 -17
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -17,7 +17,6 @@
#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -30,11 +29,6 @@ namespace agg
void rewind(unsigned) {}
unsigned vertex(double*, double*) { return path_cmd_stop; }
typedef null_markers source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
};
@@ -55,8 +49,7 @@ namespace agg
m_source(&source),
m_status(initial)
{}
void set_source(VertexSource& source) { m_source = &source; }
void attach(VertexSource& source) { m_source = &source; }
Generator& generator() { return m_generator; }
const Generator& generator() const { return m_generator; }
@@ -64,19 +57,14 @@ namespace agg
Markers& markers() { return m_markers; }
const Markers& markers() const { return m_markers; }
void rewind(unsigned id)
void rewind(unsigned path_id)
{
m_source->rewind(id);
m_source->rewind(path_id);
m_status = initial;
}
unsigned vertex(double* x, double* y);
typedef conv_adaptor_vcgen<VertexSource, Generator, Markers> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
// Prohibit copying
conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
+3 -10
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -17,7 +17,6 @@
#define AGG_CONV_ADAPTOR_VPGEN_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -27,8 +26,7 @@ namespace agg
{
public:
conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {}
void set_source(VertexSource& source) { m_source = &source; }
void attach(VertexSource& source) { m_source = &source; }
VPGen& vpgen() { return m_vpgen; }
const VPGen& vpgen() const { return m_vpgen; }
@@ -36,11 +34,6 @@ namespace agg
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
typedef conv_adaptor_vpgen<VertexSource, VPGen> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&);
const conv_adaptor_vpgen<VertexSource, VPGen>&
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+2 -8
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -29,7 +29,6 @@
#include "agg_basics.h"
#include "agg_conv_adaptor_vpgen.h"
#include "agg_vpgen_clip_polygon.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -53,11 +52,6 @@ namespace agg
double x2() const { return base_type::vpgen().x2(); }
double y2() const { return base_type::vpgen().y2(); }
typedef conv_clip_polygon<VertexSource> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_clip_polygon(const conv_clip_polygon<VertexSource>&);
const conv_clip_polygon<VertexSource>&
+2 -8
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -29,7 +29,6 @@
#include "agg_basics.h"
#include "agg_conv_adaptor_vpgen.h"
#include "agg_vpgen_clip_polyline.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -53,11 +52,6 @@ namespace agg
double x2() const { return base_type::vpgen().x2(); }
double y2() const { return base_type::vpgen().y2(); }
typedef conv_clip_polyline<VertexSource> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
const conv_clip_polyline<VertexSource>&
+3 -10
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -17,7 +17,6 @@
#define AGG_CONV_CLOSE_POLYGON_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -27,17 +26,11 @@ namespace agg
{
public:
conv_close_polygon(VertexSource& vs) : m_source(&vs) {}
void set_source(VertexSource& source) { m_source = &source; }
void attach(VertexSource& source) { m_source = &source; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
typedef conv_close_polygon<VertexSource> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_close_polygon(const conv_close_polygon<VertexSource>&);
const conv_close_polygon<VertexSource>&
+6 -13
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -17,7 +17,6 @@
#define AGG_CONV_CONCAT_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -29,14 +28,13 @@ namespace agg
public:
conv_concat(VS1& source1, VS2& source2) :
m_source1(&source1), m_source2(&source2), m_status(2) {}
void set_source1(VS1& source) { m_source1 = &source; }
void set_source2(VS2& source) { m_source2 = &source; }
void attach1(VS1& source) { m_source1 = &source; }
void attach2(VS2& source) { m_source2 = &source; }
void rewind(unsigned id)
void rewind(unsigned path_id)
{
m_source1->rewind(id);
m_source1->rewind(path_id);
m_source2->rewind(0);
m_status = 0;
}
@@ -59,11 +57,6 @@ namespace agg
return path_cmd_stop;
}
typedef conv_concat<VS1, VS2> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_concat(const conv_concat<VS1, VS2>&);
const conv_concat<VS1, VS2>&
+4 -4
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -38,7 +38,7 @@ namespace agg
}
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
void inner_line_join(line_join_e lj) { base_type::generator().inner_line_join(lj); }
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
void width(double w) { base_type::generator().width(w); }
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
@@ -47,7 +47,7 @@ namespace agg
void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); }
line_join_e line_join() const { return base_type::generator().line_join(); }
line_join_e inner_line_join() const { return base_type::generator().inner_line_join(); }
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
double width() const { return base_type::generator().width(); }
double miter_limit() const { return base_type::generator().miter_limit(); }
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
+57 -30
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -33,14 +33,14 @@ namespace agg
// and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control
// point. Curve4 has 2 control points (4 points in total) and can be used
// to interpolate more complicated curves. Curve4, unlike curve3 can be used
// to approximate arcs, both curcular and elliptical. Curves are approximated
// to approximate arcs, both circular and elliptical. Curves are approximated
// with straight lines and one of the approaches is just to store the whole
// sequence of vertices that approximate our curve. It takes additional
// memory, and at the same time the consecutive vertices can be calculated
// on demand.
//
// Initially, path storages are not suppose to keep all the vertices of the
// curves (although, nothig prevents us from doing so). Instead, path_storage
// curves (although, nothing prevents us from doing so). Instead, path_storage
// keeps only vertices, needed to calculate a curve on demand. Those vertices
// are marked with special commands. So, if the path_storage contains curves
// (which are not real curves yet), and we render this storage directly,
@@ -51,13 +51,29 @@ namespace agg
// Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4
// and converts these vertices into a move_to/line_to sequence.
//-----------------------------------------------------------------------
template<class VertexSource> class conv_curve
template<class VertexSource,
class Curve3=curve3,
class Curve4=curve4> class conv_curve
{
public:
typedef Curve3 curve3_type;
typedef Curve4 curve4_type;
typedef conv_curve<VertexSource, Curve3, Curve4> self_type;
conv_curve(VertexSource& source) :
m_source(&source), m_last_x(0.0), m_last_y(0.0) {}
void attach(VertexSource& source) { m_source = &source; }
void set_source(VertexSource& source) { m_source = &source; }
void approximation_method(curve_approximation_method_e v)
{
m_curve3.approximation_method(v);
m_curve4.approximation_method(v);
}
curve_approximation_method_e approximation_method() const
{
return m_curve4.approximation_method();
}
void approximation_scale(double s)
{
@@ -67,36 +83,52 @@ namespace agg
double approximation_scale() const
{
return m_curve3.approximation_scale();
return m_curve4.approximation_scale();
}
void rewind(unsigned id);
void angle_tolerance(double v)
{
m_curve3.angle_tolerance(v);
m_curve4.angle_tolerance(v);
}
double angle_tolerance() const
{
return m_curve4.angle_tolerance();
}
void cusp_limit(double v)
{
m_curve3.cusp_limit(v);
m_curve4.cusp_limit(v);
}
double cusp_limit() const
{
return m_curve4.cusp_limit();
}
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
typedef conv_curve<VertexSource> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_curve(const conv_curve<VertexSource>&);
const conv_curve<VertexSource>&
operator = (const conv_curve<VertexSource>&);
conv_curve(const self_type&);
const self_type& operator = (const self_type&);
VertexSource* m_source;
double m_last_x;
double m_last_y;
curve3 m_curve3;
curve4 m_curve4;
curve3_type m_curve3;
curve4_type m_curve4;
};
//------------------------------------------------------------------------
template<class VertexSource>
void conv_curve<VertexSource>::rewind(unsigned id)
template<class VertexSource, class Curve3, class Curve4>
void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id)
{
m_source->rewind(id);
m_source->rewind(path_id);
m_last_x = 0.0;
m_last_y = 0.0;
m_curve3.reset();
@@ -105,8 +137,8 @@ namespace agg
//------------------------------------------------------------------------
template<class VertexSource>
unsigned conv_curve<VertexSource>::vertex(double* x, double* y)
template<class VertexSource, class Curve3, class Curve4>
unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y)
{
if(!is_stop(m_curve3.vertex(x, y)))
{
@@ -130,13 +162,6 @@ namespace agg
unsigned cmd = m_source->vertex(x, y);
switch(cmd)
{
case path_cmd_move_to:
case path_cmd_line_to:
m_last_x = *x;
m_last_y = *y;
default:
break;
case path_cmd_curve3:
m_source->vertex(&end_x, &end_y);
@@ -163,6 +188,8 @@ namespace agg
cmd = path_cmd_line_to;
break;
}
m_last_x = *x;
m_last_y = *y;
return cmd;
}
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+15 -26
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -27,7 +27,6 @@
#include <math.h>
#include "agg_basics.h"
#include "agg_array.h"
#include "agg_vertex_iterator.h"
extern "C"
{
@@ -63,8 +62,8 @@ namespace agg
gpc_vertex* vertices;
};
typedef pod_deque<gpc_vertex, 8> vertex_array_type;
typedef pod_deque<contour_header_type, 6> contour_header_array_type;
typedef pod_bvector<gpc_vertex, 8> vertex_array_type;
typedef pod_bvector<contour_header_type, 6> contour_header_array_type;
public:
@@ -90,20 +89,15 @@ namespace agg
memset(&m_result, 0, sizeof(m_result));
}
void set_source1(VSA& source) { m_src_a = &source; }
void set_source2(VSB& source) { m_src_b = &source; }
void attach1(VSA& source) { m_src_a = &source; }
void attach2(VSB& source) { m_src_b = &source; }
void operation(gpc_op_e v) { m_operation = v; }
// Vertex Source Interface
void rewind(unsigned id);
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
// Iterator
typedef vertex_iterator<self_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_gpc(const conv_gpc<VSA, VSB>&);
const conv_gpc<VSA, VSB>& operator = (const conv_gpc<VSA, VSB>&);
@@ -197,10 +191,10 @@ namespace agg
int i;
for(i = 0; i < p.num_contours; i++)
{
delete [] p.contour[i].vertex;
pod_allocator<gpc_vertex>::deallocate(p.contour[i].vertex,
p.contour[i].num_vertices);
}
delete [] p.hole;
delete [] p.contour;
pod_allocator<gpc_vertex_list>::deallocate(p.contour, p.num_contours);
memset(&p, 0, sizeof(gpc_polygon));
}
@@ -266,7 +260,7 @@ namespace agg
// TO DO: Clarify the "holes"
//if(is_cw(orientation)) h.hole_flag = 1;
h.vertices = new gpc_vertex [h.num_vertices];
h.vertices = pod_allocator<gpc_vertex>::allocate(h.num_vertices);
gpc_vertex* d = h.vertices;
int i;
for(i = 0; i < h.num_vertices; i++)
@@ -294,19 +288,14 @@ namespace agg
{
p.num_contours = m_contour_accumulator.size();
// TO DO: Clarify the "holes"
//p.hole = new int[p.num_contours];
p.hole = 0;
p.contour = new gpc_vertex_list[p.num_contours];
p.contour = pod_allocator<gpc_vertex_list>::allocate(p.num_contours);
int i;
//int* ph = p.hole;
gpc_vertex_list* pv = p.contour;
for(i = 0; i < p.num_contours; i++)
{
const contour_header_type& h = m_contour_accumulator[i];
// *ph++ = h.hole_flag;
pv->num_vertices = h.num_vertices;
pv->vertex = h.vertices;
++pv;
@@ -356,11 +345,11 @@ namespace agg
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_gpc<VSA, VSB>::rewind(unsigned id)
void conv_gpc<VSA, VSB>::rewind(unsigned path_id)
{
free_result();
m_src_a->rewind(id);
m_src_b->rewind(id);
m_src_a->rewind(path_id);
m_src_b->rewind(path_id);
add(*m_src_a, m_poly_a);
add(*m_src_b, m_poly_b);
switch(m_operation)
+3 -9
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -21,7 +21,6 @@
#include "agg_basics.h"
#include "agg_trans_affine.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -35,14 +34,9 @@ namespace agg
trans_affine& transform() { return m_transform; }
const trans_affine& transform() const { return m_transform; }
void rewind(unsigned id);
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
typedef conv_marker<MarkerLocator, MarkerShapes> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_marker(const conv_marker<MarkerLocator, MarkerShapes>&);
const conv_marker<MarkerLocator, MarkerShapes>&
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+8 -8
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -39,13 +39,13 @@ namespace agg
{
}
void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); }
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
void inner_line_join(line_join_e lj) { base_type::generator().inner_line_join(lj); }
void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); }
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
line_cap_e line_cap() const { return base_type::generator().line_cap(); }
line_join_e line_join() const { return base_type::generator().line_join(); }
line_join_e inner_line_join() const { return base_type::generator().inner_line_join(); }
line_cap_e line_cap() const { return base_type::generator().line_cap(); }
line_join_e line_join() const { return base_type::generator().line_join(); }
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
void width(double w) { base_type::generator().width(w); }
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
+5 -12
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -21,7 +21,6 @@
#include "agg_basics.h"
#include "agg_trans_affine.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -32,12 +31,11 @@ namespace agg
public:
conv_transform(VertexSource& source, const Transformer& tr) :
m_source(&source), m_trans(&tr) {}
void attach(VertexSource& source) { m_source = &source; }
void set_source(VertexSource& source) { m_source = &source; }
void rewind(unsigned id)
void rewind(unsigned path_id)
{
m_source->rewind(id);
m_source->rewind(path_id);
}
unsigned vertex(double* x, double* y)
@@ -55,11 +53,6 @@ namespace agg
m_trans = &tr;
}
typedef conv_transform<VertexSource, Transformer> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_transform(const conv_transform<VertexSource>&);
const conv_transform<VertexSource>&
+3 -10
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -17,7 +17,6 @@
#define AGG_CONV_UNCLOSE_POLYGON_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -26,8 +25,7 @@ namespace agg
{
public:
conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {}
void set_source(VertexSource& source) { m_source = &source; }
void attach(VertexSource& source) { m_source = &source; }
void rewind(unsigned path_id)
{
@@ -41,11 +39,6 @@ namespace agg
return cmd;
}
typedef conv_unclose_polygon<VertexSource> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_unclose_polygon(const conv_unclose_polygon<VertexSource>&);
const conv_unclose_polygon<VertexSource>&
+586 -43
View File
@@ -1,6 +1,7 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// Copyright (C) 2005 Tony Juricic ([email protected])
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
@@ -12,34 +13,35 @@
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// classes curve3 and curve4
//
//----------------------------------------------------------------------------
#ifndef AGG_CURVES_INCLUDED
#define AGG_CURVES_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_iterator.h"
#include "agg_array.h"
namespace agg
{
// See Implemantation agg_curves.cpp
// See Implementation agg_curves.cpp
//--------------------------------------------curve_approximation_method_e
enum curve_approximation_method_e
{
curve_inc,
curve_div
};
//------------------------------------------------------------------curve3
class curve3
//--------------------------------------------------------------curve3_inc
class curve3_inc
{
public:
curve3() :
curve3_inc() :
m_num_steps(0), m_step(0), m_scale(1.0) { }
curve3(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_num_steps(0), m_step(0), m_scale(1.0)
curve3_inc(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_num_steps(0), m_step(0), m_scale(1.0)
{
init(x1, y1, x2, y2, x3, y3);
}
@@ -48,17 +50,22 @@ namespace agg
void init(double x1, double y1,
double x2, double y2,
double x3, double y3);
void approximation_scale(double s) { m_scale = s; }
double approximation_scale() const { return m_scale; }
void rewind(unsigned id);
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const { return curve_inc; }
void approximation_scale(double s);
double approximation_scale() const;
void angle_tolerance(double) {}
double angle_tolerance() const { return 0.0; }
void cusp_limit(double) {}
double cusp_limit() const { return 0.0; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
typedef curve3 source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
int m_num_steps;
int m_step;
@@ -83,41 +90,154 @@ namespace agg
//-----------------------------------------------------------------curve4
class curve4
//-------------------------------------------------------------curve3_div
class curve3_div
{
public:
curve4() :
m_num_steps(0), m_step(0), m_scale(1.0) { }
curve3_div() :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_count(0)
{}
curve4(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_num_steps(0), m_step(0), m_scale(1.0)
curve3_div(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_count(0)
{
init(x1, y1, x2, y2, x3, y3);
}
void reset() { m_points.remove_all(); m_count = 0; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3);
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const { return curve_div; }
void approximation_scale(double s) { m_approximation_scale = s; }
double approximation_scale() const { return m_approximation_scale; }
void angle_tolerance(double a) { m_angle_tolerance = a; }
double angle_tolerance() const { return m_angle_tolerance; }
void cusp_limit(double) {}
double cusp_limit() const { return 0.0; }
void rewind(unsigned)
{
m_count = 0;
}
unsigned vertex(double* x, double* y)
{
if(m_count >= m_points.size()) return path_cmd_stop;
const point_d& p = m_points[m_count++];
*x = p.x;
*y = p.y;
return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
}
private:
void bezier(double x1, double y1,
double x2, double y2,
double x3, double y3);
void recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
unsigned level);
double m_approximation_scale;
double m_distance_tolerance_square;
double m_angle_tolerance;
unsigned m_count;
pod_bvector<point_d> m_points;
};
//-------------------------------------------------------------curve4_points
struct curve4_points
{
double cp[8];
curve4_points() {}
curve4_points(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
}
double operator [] (unsigned i) const { return cp[i]; }
double& operator [] (unsigned i) { return cp[i]; }
};
//-------------------------------------------------------------curve4_inc
class curve4_inc
{
public:
curve4_inc() :
m_num_steps(0), m_step(0), m_scale(1.0) { }
curve4_inc(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_num_steps(0), m_step(0), m_scale(1.0)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
curve4_inc(const curve4_points& cp) :
m_num_steps(0), m_step(0), m_scale(1.0)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void reset() { m_num_steps = 0; m_step = -1; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
void approximation_scale(double s) { m_scale = s; }
double approximation_scale() const { return m_scale; }
void init(const curve4_points& cp)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void rewind(unsigned id);
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const { return curve_inc; }
void approximation_scale(double s);
double approximation_scale() const;
void angle_tolerance(double) {}
double angle_tolerance() const { return 0.0; }
void cusp_limit(double) {}
double cusp_limit() const { return 0.0; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
typedef curve4 source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
int m_num_steps;
int m_step;
@@ -144,6 +264,429 @@ namespace agg
//-------------------------------------------------------catrom_to_bezier
inline curve4_points catrom_to_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
// Trans. matrix Catmull-Rom to Bezier
//
// 0 1 0 0
// -1/6 1 1/6 0
// 0 1/6 1 -1/6
// 0 0 1 0
//
return curve4_points(
x2,
y2,
(-x1 + 6*x2 + x3) / 6,
(-y1 + 6*y2 + y3) / 6,
( x2 + 6*x3 - x4) / 6,
( y2 + 6*y3 - y4) / 6,
x3,
y3);
}
//-----------------------------------------------------------------------
inline curve4_points
catrom_to_bezier(const curve4_points& cp)
{
return catrom_to_bezier(cp[0], cp[1], cp[2], cp[3],
cp[4], cp[5], cp[6], cp[7]);
}
//-----------------------------------------------------ubspline_to_bezier
inline curve4_points ubspline_to_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
// Trans. matrix Uniform BSpline to Bezier
//
// 1/6 4/6 1/6 0
// 0 4/6 2/6 0
// 0 2/6 4/6 0
// 0 1/6 4/6 1/6
//
return curve4_points(
(x1 + 4*x2 + x3) / 6,
(y1 + 4*y2 + y3) / 6,
(4*x2 + 2*x3) / 6,
(4*y2 + 2*y3) / 6,
(2*x2 + 4*x3) / 6,
(2*y2 + 4*y3) / 6,
(x2 + 4*x3 + x4) / 6,
(y2 + 4*y3 + y4) / 6);
}
//-----------------------------------------------------------------------
inline curve4_points
ubspline_to_bezier(const curve4_points& cp)
{
return ubspline_to_bezier(cp[0], cp[1], cp[2], cp[3],
cp[4], cp[5], cp[6], cp[7]);
}
//------------------------------------------------------hermite_to_bezier
inline curve4_points hermite_to_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
// Trans. matrix Hermite to Bezier
//
// 1 0 0 0
// 1 0 1/3 0
// 0 1 0 -1/3
// 0 1 0 0
//
return curve4_points(
x1,
y1,
(3*x1 + x3) / 3,
(3*y1 + y3) / 3,
(3*x2 - x4) / 3,
(3*y2 - y4) / 3,
x2,
y2);
}
//-----------------------------------------------------------------------
inline curve4_points
hermite_to_bezier(const curve4_points& cp)
{
return hermite_to_bezier(cp[0], cp[1], cp[2], cp[3],
cp[4], cp[5], cp[6], cp[7]);
}
//-------------------------------------------------------------curve4_div
class curve4_div
{
public:
curve4_div() :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_cusp_limit(0.0),
m_count(0)
{}
curve4_div(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_cusp_limit(0.0),
m_count(0)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
curve4_div(const curve4_points& cp) :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_count(0)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void reset() { m_points.remove_all(); m_count = 0; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
void init(const curve4_points& cp)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const
{
return curve_div;
}
void approximation_scale(double s) { m_approximation_scale = s; }
double approximation_scale() const { return m_approximation_scale; }
void angle_tolerance(double a) { m_angle_tolerance = a; }
double angle_tolerance() const { return m_angle_tolerance; }
void cusp_limit(double v)
{
m_cusp_limit = (v == 0.0) ? 0.0 : pi - v;
}
double cusp_limit() const
{
return (m_cusp_limit == 0.0) ? 0.0 : pi - m_cusp_limit;
}
void rewind(unsigned)
{
m_count = 0;
}
unsigned vertex(double* x, double* y)
{
if(m_count >= m_points.size()) return path_cmd_stop;
const point_d& p = m_points[m_count++];
*x = p.x;
*y = p.y;
return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
}
private:
void bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
void recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4,
unsigned level);
double m_approximation_scale;
double m_distance_tolerance_square;
double m_angle_tolerance;
double m_cusp_limit;
unsigned m_count;
pod_bvector<point_d> m_points;
};
//-----------------------------------------------------------------curve3
class curve3
{
public:
curve3() : m_approximation_method(curve_div) {}
curve3(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_approximation_method(curve_div)
{
init(x1, y1, x2, y2, x3, y3);
}
void reset()
{
m_curve_inc.reset();
m_curve_div.reset();
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.init(x1, y1, x2, y2, x3, y3);
}
else
{
m_curve_div.init(x1, y1, x2, y2, x3, y3);
}
}
void approximation_method(curve_approximation_method_e v)
{
m_approximation_method = v;
}
curve_approximation_method_e approximation_method() const
{
return m_approximation_method;
}
void approximation_scale(double s)
{
m_curve_inc.approximation_scale(s);
m_curve_div.approximation_scale(s);
}
double approximation_scale() const
{
return m_curve_inc.approximation_scale();
}
void angle_tolerance(double a)
{
m_curve_div.angle_tolerance(a);
}
double angle_tolerance() const
{
return m_curve_div.angle_tolerance();
}
void cusp_limit(double v)
{
m_curve_div.cusp_limit(v);
}
double cusp_limit() const
{
return m_curve_div.cusp_limit();
}
void rewind(unsigned path_id)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.rewind(path_id);
}
else
{
m_curve_div.rewind(path_id);
}
}
unsigned vertex(double* x, double* y)
{
if(m_approximation_method == curve_inc)
{
return m_curve_inc.vertex(x, y);
}
return m_curve_div.vertex(x, y);
}
private:
curve3_inc m_curve_inc;
curve3_div m_curve_div;
curve_approximation_method_e m_approximation_method;
};
//-----------------------------------------------------------------curve4
class curve4
{
public:
curve4() : m_approximation_method(curve_div) {}
curve4(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_approximation_method(curve_div)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
curve4(const curve4_points& cp) :
m_approximation_method(curve_div)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void reset()
{
m_curve_inc.reset();
m_curve_div.reset();
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.init(x1, y1, x2, y2, x3, y3, x4, y4);
}
else
{
m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4);
}
}
void init(const curve4_points& cp)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void approximation_method(curve_approximation_method_e v)
{
m_approximation_method = v;
}
curve_approximation_method_e approximation_method() const
{
return m_approximation_method;
}
void approximation_scale(double s)
{
m_curve_inc.approximation_scale(s);
m_curve_div.approximation_scale(s);
}
double approximation_scale() const { return m_curve_inc.approximation_scale(); }
void angle_tolerance(double v)
{
m_curve_div.angle_tolerance(v);
}
double angle_tolerance() const
{
return m_curve_div.angle_tolerance();
}
void cusp_limit(double v)
{
m_curve_div.cusp_limit(v);
}
double cusp_limit() const
{
return m_curve_div.cusp_limit();
}
void rewind(unsigned path_id)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.rewind(path_id);
}
else
{
m_curve_div.rewind(path_id);
}
}
unsigned vertex(double* x, double* y)
{
if(m_approximation_method == curve_inc)
{
return m_curve_inc.vertex(x, y);
}
return m_curve_div.vertex(x, y);
}
private:
curve4_inc m_curve_inc;
curve4_div m_curve_div;
curve_approximation_method_e m_approximation_method;
};
}
+6 -6
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -86,7 +86,7 @@ namespace agg
{
public:
typedef int save_data_type;
enum { save_size = 2 };
enum save_size_e { save_size = 2 };
//--------------------------------------------------------------------
dda2_line_interpolator() {}
@@ -217,11 +217,11 @@ namespace agg
class line_bresenham_interpolator
{
public:
enum
enum subpixel_scale_e
{
subpixel_shift = 8,
subpixel_size = 1 << subpixel_shift,
subpixel_mask = subpixel_size - 1
subpixel_scale = 1 << subpixel_shift,
subpixel_mask = subpixel_scale - 1
};
//--------------------------------------------------------------------
+36 -11
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -30,27 +30,41 @@ namespace agg
class ellipse
{
public:
ellipse() : m_x(0.0), m_y(0.0), m_rx(1.0), m_ry(1.0), m_num(4), m_step(0) {}
ellipse(double x, double y, double rx, double ry, unsigned num_steps)
: m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_num(num_steps), m_step(0) {}
ellipse() :
m_x(0.0), m_y(0.0), m_rx(1.0), m_ry(1.0), m_scale(1.0),
m_num(4), m_step(0), m_cw(false) {}
ellipse(double x, double y, double rx, double ry,
unsigned num_steps=0, bool cw=false) :
m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0),
m_num(num_steps), m_step(0), m_cw(cw)
{
if(m_num == 0) calc_num_steps();
}
void init(double x, double y, double rx, double ry,
unsigned num_steps=0, bool cw=false);
void init(double x, double y, double rx, double ry, unsigned num_steps);
void approximation_scale(double scale);
void rewind(unsigned id);
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
void calc_num_steps();
double m_x;
double m_y;
double m_rx;
double m_ry;
double m_scale;
unsigned m_num;
unsigned m_step;
bool m_cw;
};
//------------------------------------------------------------------------
inline void ellipse::init(double x, double y, double rx, double ry, unsigned num_steps)
inline void ellipse::init(double x, double y, double rx, double ry,
unsigned num_steps, bool cw)
{
m_x = x;
m_y = y;
@@ -58,13 +72,23 @@ namespace agg
m_ry = ry;
m_num = num_steps;
m_step = 0;
m_cw = cw;
if(m_num == 0) calc_num_steps();
}
//------------------------------------------------------------------------
inline void ellipse::approximation_scale(double scale)
{
m_num = unsigned((fabs(m_rx) + fabs(m_ry) + 6.0) * scale);
if(m_num < 6) m_num = 6;
m_scale = scale;
calc_num_steps();
}
//------------------------------------------------------------------------
inline void ellipse::calc_num_steps()
{
double ra = (fabs(m_rx) + fabs(m_ry)) / 2;
double da = acos(ra / (ra + 0.125 / m_scale)) * 2;
m_num = uround(2*pi / da);
}
//------------------------------------------------------------------------
@@ -83,6 +107,7 @@ namespace agg
}
if(m_step > m_num) return path_cmd_stop;
double angle = double(m_step) / double(m_num) * 2.0 * pi;
if(m_cw) angle = 2.0 * pi - angle;
*x = m_x + cos(angle) * m_rx;
*y = m_y + sin(angle) * m_ry;
m_step++;
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+28 -22
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -39,7 +39,7 @@ namespace agg
int8u* data;
unsigned data_size;
glyph_data_type data_type;
rect bounds;
rect_i bounds;
double advance_x;
double advance_y;
};
@@ -49,12 +49,16 @@ namespace agg
class font_cache
{
public:
enum { block_size = 16384-16 };
enum block_size_e { block_size = 16384-16 };
//--------------------------------------------------------------------
font_cache(const char* font_signature) :
font_cache() :
m_allocator(block_size),
m_font_signature(0)
{}
//--------------------------------------------------------------------
void signature(const char* font_signature)
{
m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1);
strcpy(m_font_signature, font_signature);
@@ -83,7 +87,7 @@ namespace agg
unsigned glyph_index,
unsigned data_size,
glyph_data_type data_type,
const rect& bounds,
const rect_i& bounds,
double advance_x,
double advance_y)
{
@@ -103,18 +107,18 @@ namespace agg
(glyph_cache*)m_allocator.allocate(sizeof(glyph_cache),
sizeof(double));
glyph->glyph_index = glyph_index;
glyph->data = m_allocator.allocate(data_size);
glyph->data_size = data_size;
glyph->data_type = data_type;
glyph->bounds = bounds;
glyph->advance_x = advance_x;
glyph->advance_y = advance_y;
glyph->glyph_index = glyph_index;
glyph->data = m_allocator.allocate(data_size);
glyph->data_size = data_size;
glyph->data_type = data_type;
glyph->bounds = bounds;
glyph->advance_x = advance_x;
glyph->advance_y = advance_y;
return m_glyphs[msb][lsb] = glyph;
}
private:
pod_allocator m_allocator;
block_allocator m_allocator;
glyph_cache** m_glyphs[256];
char* m_font_signature;
};
@@ -135,14 +139,14 @@ namespace agg
unsigned i;
for(i = 0; i < m_num_fonts; ++i)
{
delete m_fonts[i];
obj_allocator<font_cache>::deallocate(m_fonts[i]);
}
delete [] m_fonts;
pod_allocator<font_cache*>::deallocate(m_fonts, m_max_fonts);
}
//--------------------------------------------------------------------
font_cache_pool(unsigned max_fonts=32) :
m_fonts(new font_cache* [max_fonts]),
m_fonts(pod_allocator<font_cache*>::allocate(max_fonts)),
m_max_fonts(max_fonts),
m_num_fonts(0),
m_cur_font(0)
@@ -157,8 +161,9 @@ namespace agg
{
if(reset_cache)
{
delete m_fonts[idx];
m_fonts[idx] = new font_cache(font_signature);
obj_allocator<font_cache>::deallocate(m_fonts[idx]);
m_fonts[idx] = obj_allocator<font_cache>::allocate();
m_fonts[idx]->signature(font_signature);
}
m_cur_font = m_fonts[idx];
}
@@ -166,13 +171,14 @@ namespace agg
{
if(m_num_fonts >= m_max_fonts)
{
delete m_fonts[0];
obj_allocator<font_cache>::deallocate(m_fonts[0]);
memcpy(m_fonts,
m_fonts + 1,
(m_max_fonts - 1) * sizeof(font_cache*));
m_num_fonts = m_max_fonts - 1;
}
m_fonts[m_num_fonts] = new font_cache(font_signature);
m_fonts[m_num_fonts] = obj_allocator<font_cache>::allocate();
m_fonts[m_num_fonts]->signature(font_signature);
m_cur_font = m_fonts[m_num_fonts];
++m_num_fonts;
}
@@ -196,7 +202,7 @@ namespace agg
unsigned glyph_index,
unsigned data_size,
glyph_data_type data_type,
const rect& bounds,
const rect_i& bounds,
double advance_x,
double advance_y)
{
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+19 -12
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -27,14 +27,16 @@ namespace agg
unsigned HiResShift=8> class gamma_lut
{
public:
enum
typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type;
enum gamma_scale_e
{
gamma_shift = GammaShift,
gamma_size = 1 << gamma_shift,
gamma_mask = gamma_size - 1
};
enum
enum hi_res_scale_e
{
hi_res_shift = HiResShift,
hi_res_size = 1 << hi_res_shift,
@@ -43,14 +45,14 @@ namespace agg
~gamma_lut()
{
delete [] m_inv_gamma;
delete [] m_dir_gamma;
pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size);
pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size);
}
gamma_lut() :
m_gamma(1.0),
m_dir_gamma(new HiResT[gamma_size]),
m_inv_gamma(new LoResT[hi_res_size])
m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
{
unsigned i;
for(i = 0; i < gamma_size; i++)
@@ -66,8 +68,8 @@ namespace agg
gamma_lut(double g) :
m_gamma(1.0),
m_dir_gamma(new HiResT[gamma_size]),
m_inv_gamma(new LoResT[hi_res_size])
m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
{
gamma(g);
}
@@ -79,13 +81,15 @@ namespace agg
unsigned i;
for(i = 0; i < gamma_size; i++)
{
m_dir_gamma[i] = (HiResT)(pow(double(i) / double(gamma_mask), m_gamma) * double(hi_res_mask) + 0.5);
m_dir_gamma[i] = (HiResT)
uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask));
}
double inv_g = 1.0 / g;
for(i = 0; i < hi_res_size; i++)
{
m_inv_gamma[i] = (LoResT)(pow(double(i) / double(hi_res_mask), inv_g) * double(gamma_mask) + 0.5);
m_inv_gamma[i] = (LoResT)
uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask));
}
}
@@ -105,6 +109,9 @@ namespace agg
}
private:
gamma_lut(const self_type&);
const self_type& operator = (const self_type&);
double m_gamma;
HiResT* m_dir_gamma;
LoResT* m_inv_gamma;
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
-108
View File
@@ -1,108 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// color type gray8
//
//----------------------------------------------------------------------------
#ifndef AGG_GRAY8_INCLUDED
#define AGG_GRAY8_INCLUDED
#include "agg_basics.h"
#include "agg_color_rgba.h"
#include "agg_color_rgba8.h"
namespace agg
{
//===================================================================gray8
struct gray8
{
typedef int8u alpha_type;
int8u v;
int8u a;
//--------------------------------------------------------------------
gray8() {}
//--------------------------------------------------------------------
gray8(unsigned v_, unsigned a_=255) :
v(int8u(v_)), a(int8u(a_)) {}
//--------------------------------------------------------------------
gray8(const rgba& c) :
v(int8u((0.299*c.r + 0.587*c.g + 0.114*c.b) * 255.0 + 0.5)),
a(int8u(c.a*255.0)) {}
//--------------------------------------------------------------------
gray8(const rgba8& c) :
v((c.r*77 + c.g*150 + c.b*29) >> 8),
a(c.a) {}
//--------------------------------------------------------------------
void clear()
{
v = a = 0;
}
//--------------------------------------------------------------------
const gray8& transparent()
{
a = 0;
return *this;
}
//--------------------------------------------------------------------
void opacity(double a_)
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
a = int8u(a_ * 255.0);
}
//--------------------------------------------------------------------
double opacity() const
{
return double(a) / 255.0;
}
//--------------------------------------------------------------------
gray8 gradient(gray8 c, double k) const
{
gray8 ret;
int ik = int(k * 256);
ret.v = int8u(int(v) + (((int(c.v) - int(v)) * ik) >> 8));
ret.a = int8u(int(a) + (((int(c.a) - int(a)) * ik) >> 8));
return ret;
}
//--------------------------------------------------------------------
gray8 pre() const
{
return gray8((v*a) >> 8, a);
}
//--------------------------------------------------------------------
static gray8 no_color() { return gray8(0,0); }
};
}
#endif
+28 -31
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -20,7 +20,7 @@
#ifndef AGG_GSV_TEXT_INCLUDED
#define AGG_GSV_TEXT_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
#include "agg_conv_stroke.h"
#include "agg_conv_transform.h"
@@ -43,7 +43,6 @@ namespace agg
};
public:
~gsv_text();
gsv_text();
void font(const void* font);
@@ -55,7 +54,7 @@ namespace agg
void start_point(double x, double y);
void text(const char* text);
void rewind(unsigned id);
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
@@ -80,30 +79,28 @@ namespace agg
}
private:
double m_x;
double m_y;
double m_start_x;
double m_width;
double m_height;
double m_space;
double m_line_space;
char m_chr[2];
char* m_text;
char* m_text_buf;
unsigned m_buf_size;
char* m_cur_chr;
const void* m_font;
char* m_loaded_font;
status m_status;
bool m_big_endian;
bool m_flip;
int8u* m_indices;
int8* m_glyphs;
int8* m_bglyph;
int8* m_eglyph;
double m_w;
double m_h;
double m_x;
double m_y;
double m_start_x;
double m_width;
double m_height;
double m_space;
double m_line_space;
char m_chr[2];
char* m_text;
pod_array<char> m_text_buf;
char* m_cur_chr;
const void* m_font;
pod_array<char> m_loaded_font;
status m_status;
bool m_big_endian;
bool m_flip;
int8u* m_indices;
int8* m_glyphs;
int8* m_bglyph;
int8* m_eglyph;
double m_w;
double m_h;
};
@@ -129,9 +126,9 @@ namespace agg
m_trans->transformer(trans);
}
void rewind(unsigned id)
void rewind(unsigned path_id)
{
m_trans.rewind(id);
m_trans.rewind(path_id);
m_polyline.line_join(round_join);
m_polyline.line_cap(round_cap);
}
+476
View File
@@ -0,0 +1,476 @@
//----------------------------------------------------------------------------
// 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_IMAGE_ACCESSORS_INCLUDED
#define AGG_IMAGE_ACCESSORS_INCLUDED
#include "agg_basics.h"
namespace agg
{
//-----------------------------------------------------image_accessor_clip
template<class PixFmt> class image_accessor_clip
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::order_type order_type;
typedef typename pixfmt_type::value_type value_type;
enum pix_width_e { pix_width = pixfmt_type::pix_width };
image_accessor_clip() {}
image_accessor_clip(const pixfmt_type& pixf, const color_type& bk) :
m_pixf(&pixf)
{
pixfmt_type::make_pix(m_bk_buf, bk);
}
void attach(const pixfmt_type& pixf)
{
m_pixf = &pixf;
}
void background_color(const color_type& bk)
{
pixfmt_type::make_pix(m_bk_buf, bk);
}
private:
AGG_INLINE const int8u* pixel() const
{
if(m_y >= 0 && m_y < (int)m_pixf->height() &&
m_x >= 0 && m_x < (int)m_pixf->width())
{
return m_pixf->pix_ptr(m_x, m_y);
}
return m_bk_buf;
}
public:
AGG_INLINE const int8u* span(int x, int y, unsigned len)
{
m_x = m_x0 = x;
m_y = y;
if(y >= 0 && y < (int)m_pixf->height() &&
x >= 0 && x+(int)len <= (int)m_pixf->width())
{
return m_pix_ptr = m_pixf->pix_ptr(x, y);
}
m_pix_ptr = 0;
return pixel();
}
AGG_INLINE const int8u* next_x()
{
if(m_pix_ptr) return m_pix_ptr += pix_width;
++m_x;
return pixel();
}
AGG_INLINE const int8u* next_y()
{
++m_y;
m_x = m_x0;
if(m_pix_ptr &&
m_y >= 0 && m_y < (int)m_pixf->height())
{
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
}
m_pix_ptr = 0;
return pixel();
}
private:
const pixfmt_type* m_pixf;
int8u m_bk_buf[4];
int m_x, m_x0, m_y;
const int8u* m_pix_ptr;
};
//--------------------------------------------------image_accessor_no_clip
template<class PixFmt> class image_accessor_no_clip
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::order_type order_type;
typedef typename pixfmt_type::value_type value_type;
enum pix_width_e { pix_width = pixfmt_type::pix_width };
image_accessor_no_clip() {}
image_accessor_no_clip(const pixfmt_type& pixf) : m_pixf(&pixf) {}
void attach(const pixfmt_type& pixf)
{
m_pixf = &pixf;
}
AGG_INLINE const int8u* span(int x, int y, unsigned)
{
m_x = x;
m_y = y;
return m_pix_ptr = m_pixf->pix_ptr(x, y);
}
AGG_INLINE const int8u* next_x()
{
return m_pix_ptr += pix_width;
}
AGG_INLINE const int8u* next_y()
{
++m_y;
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
}
private:
const pixfmt_type* m_pixf;
int m_x, m_y;
const int8u* m_pix_ptr;
};
//----------------------------------------------------image_accessor_clone
template<class PixFmt> class image_accessor_clone
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::order_type order_type;
typedef typename pixfmt_type::value_type value_type;
enum pix_width_e { pix_width = pixfmt_type::pix_width };
image_accessor_clone() {}
image_accessor_clone(const pixfmt_type& pixf) : m_pixf(&pixf) {}
void attach(const pixfmt_type& pixf)
{
m_pixf = &pixf;
}
private:
AGG_INLINE const int8u* pixel() const
{
register int x = m_x;
register int y = m_y;
if(x < 0) x = 0;
if(y < 0) y = 0;
if(x >= (int)m_pixf->width()) x = m_pixf->width() - 1;
if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1;
return m_pixf->pix_ptr(x, y);
}
public:
AGG_INLINE const int8u* span(int x, int y, unsigned len)
{
m_x = m_x0 = x;
m_y = y;
if(y >= 0 && y < (int)m_pixf->height() &&
x >= 0 && x+len <= (int)m_pixf->width())
{
return m_pix_ptr = m_pixf->pix_ptr(x, y);
}
m_pix_ptr = 0;
return pixel();
}
AGG_INLINE const int8u* next_x()
{
if(m_pix_ptr) return m_pix_ptr += pix_width;
++m_x;
return pixel();
}
AGG_INLINE const int8u* next_y()
{
++m_y;
m_x = m_x0;
if(m_pix_ptr &&
m_y >= 0 && m_y < (int)m_pixf->height())
{
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
}
m_pix_ptr = 0;
return pixel();
}
private:
const pixfmt_type* m_pixf;
int m_x, m_x0, m_y;
const int8u* m_pix_ptr;
};
//-----------------------------------------------------image_accessor_wrap
template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::order_type order_type;
typedef typename pixfmt_type::value_type value_type;
enum pix_width_e { pix_width = pixfmt_type::pix_width };
image_accessor_wrap() {}
image_accessor_wrap(const pixfmt_type& pixf) :
m_pixf(&pixf),
m_wrap_x(pixf.width()),
m_wrap_y(pixf.height())
{}
void attach(const pixfmt_type& pixf)
{
m_pixf = &pixf;
}
AGG_INLINE const int8u* span(int x, int y, unsigned)
{
m_x = x;
m_row_ptr = m_pixf->row_ptr(m_wrap_y(y));
return m_row_ptr + m_wrap_x(x) * pix_width;
}
AGG_INLINE const int8u* next_x()
{
int x = ++m_wrap_x;
return m_row_ptr + x * pix_width;
}
AGG_INLINE const int8u* next_y()
{
m_row_ptr = m_pixf->row_ptr(++m_wrap_y);
return m_row_ptr + m_wrap_x(m_x) * pix_width;
}
private:
const pixfmt_type* m_pixf;
const int8u* m_row_ptr;
int m_x;
WrapX m_wrap_x;
WrapY m_wrap_y;
};
//--------------------------------------------------------wrap_mode_repeat
class wrap_mode_repeat
{
public:
wrap_mode_repeat() {}
wrap_mode_repeat(unsigned size) :
m_size(size),
m_add(size * (0x3FFFFFFF / size)),
m_value(0)
{}
AGG_INLINE unsigned operator() (int v)
{
return m_value = (unsigned(v) + m_add) % m_size;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
if(m_value >= m_size) m_value = 0;
return m_value;
}
private:
unsigned m_size;
unsigned m_add;
unsigned m_value;
};
//---------------------------------------------------wrap_mode_repeat_pow2
class wrap_mode_repeat_pow2
{
public:
wrap_mode_repeat_pow2() {}
wrap_mode_repeat_pow2(unsigned size) : m_value(0)
{
m_mask = 1;
while(m_mask < size) m_mask = (m_mask << 1) | 1;
m_mask >>= 1;
}
AGG_INLINE unsigned operator() (int v)
{
return m_value = unsigned(v) & m_mask;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
if(m_value > m_mask) m_value = 0;
return m_value;
}
private:
unsigned m_mask;
unsigned m_value;
};
//----------------------------------------------wrap_mode_repeat_auto_pow2
class wrap_mode_repeat_auto_pow2
{
public:
wrap_mode_repeat_auto_pow2() {}
wrap_mode_repeat_auto_pow2(unsigned size) :
m_size(size),
m_add(size * (0x3FFFFFFF / size)),
m_mask((m_size & (m_size-1)) ? 0 : m_size-1),
m_value(0)
{}
AGG_INLINE unsigned operator() (int v)
{
if(m_mask) return m_value = unsigned(v) & m_mask;
return m_value = (unsigned(v) + m_add) % m_size;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
if(m_value >= m_size) m_value = 0;
return m_value;
}
private:
unsigned m_size;
unsigned m_add;
unsigned m_mask;
unsigned m_value;
};
//-------------------------------------------------------wrap_mode_reflect
class wrap_mode_reflect
{
public:
wrap_mode_reflect() {}
wrap_mode_reflect(unsigned size) :
m_size(size),
m_size2(size * 2),
m_add(m_size2 * (0x3FFFFFFF / m_size2)),
m_value(0)
{}
AGG_INLINE unsigned operator() (int v)
{
m_value = (unsigned(v) + m_add) % m_size2;
if(m_value >= m_size) return m_size2 - m_value - 1;
return m_value;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
if(m_value >= m_size2) m_value = 0;
if(m_value >= m_size) return m_size2 - m_value - 1;
return m_value;
}
private:
unsigned m_size;
unsigned m_size2;
unsigned m_add;
unsigned m_value;
};
//--------------------------------------------------wrap_mode_reflect_pow2
class wrap_mode_reflect_pow2
{
public:
wrap_mode_reflect_pow2() {}
wrap_mode_reflect_pow2(unsigned size) : m_value(0)
{
m_mask = 1;
m_size = 1;
while(m_mask < size)
{
m_mask = (m_mask << 1) | 1;
m_size <<= 1;
}
}
AGG_INLINE unsigned operator() (int v)
{
m_value = unsigned(v) & m_mask;
if(m_value >= m_size) return m_mask - m_value;
return m_value;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
m_value &= m_mask;
if(m_value >= m_size) return m_mask - m_value;
return m_value;
}
private:
unsigned m_size;
unsigned m_mask;
unsigned m_value;
};
//---------------------------------------------wrap_mode_reflect_auto_pow2
class wrap_mode_reflect_auto_pow2
{
public:
wrap_mode_reflect_auto_pow2() {}
wrap_mode_reflect_auto_pow2(unsigned size) :
m_size(size),
m_size2(size * 2),
m_add(m_size2 * (0x3FFFFFFF / m_size2)),
m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
m_value(0)
{}
AGG_INLINE unsigned operator() (int v)
{
m_value = m_mask ? unsigned(v) & m_mask :
(unsigned(v) + m_add) % m_size2;
if(m_value >= m_size) return m_size2 - m_value - 1;
return m_value;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
if(m_value >= m_size2) m_value = 0;
if(m_value >= m_size) return m_size2 - m_value - 1;
return m_value;
}
private:
unsigned m_size;
unsigned m_size2;
unsigned m_add;
unsigned m_mask;
unsigned m_value;
};
}
#endif
+304 -223
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -14,86 +14,95 @@
//----------------------------------------------------------------------------
//
// Image transformation filters,
// Filtering classes (image_filter_base, image_filter),
// Basic filter shape classes:
// image_filter_bilinear,
// image_filter_bicubic,
// image_filter_spline16,
// image_filter_spline36,
// image_filter_sinc64,
// image_filter_sinc144,
// image_filter_sinc196,
// image_filter_sinc256
//
// Filtering classes (image_filter_lut, image_filter),
// Basic filter shape classes
//----------------------------------------------------------------------------
#ifndef AGG_IMAGE_FILTERS_INCLUDED
#define AGG_IMAGE_FILTERS_INCLUDED
#include <math.h>
#include "agg_basics.h"
#include "agg_array.h"
#include "agg_math.h"
namespace agg
{
// See Implementation agg_image_filters.cpp
enum
enum image_filter_scale_e
{
image_filter_shift = 14, //----image_filter_shift
image_filter_size = 1 << image_filter_shift, //----image_filter_size
image_filter_mask = image_filter_size - 1, //----image_filter_mask
image_filter_scale = 1 << image_filter_shift, //----image_filter_scale
image_filter_mask = image_filter_scale - 1 //----image_filter_mask
};
enum image_subpixel_scale_e
{
image_subpixel_shift = 8, //----image_subpixel_shift
image_subpixel_size = 1 << image_subpixel_shift, //----image_subpixel_size
image_subpixel_mask = image_subpixel_size - 1 //----image_subpixel_mask
image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale
image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask
};
//-----------------------------------------------------image_filter_base
class image_filter_base
//-----------------------------------------------------image_filter_lut
class image_filter_lut
{
public:
~image_filter_base();
template<class FilterF> void calculate(const FilterF& filter,
bool normalization=true)
{
double r = filter.radius();
realloc_lut(r);
unsigned i;
unsigned pivot = diameter() << (image_subpixel_shift - 1);
for(i = 0; i < pivot; i++)
{
double x = double(i) / double(image_subpixel_scale);
double y = filter.calc_weight(x);
m_weight_array[pivot + i] =
m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale);
}
unsigned end = (diameter() << image_subpixel_shift) - 1;
m_weight_array[0] = m_weight_array[end];
if(normalization)
{
normalize();
}
}
image_filter_base(unsigned dimension);
image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {}
unsigned dimension() const { return m_dimension; }
int start() const { return m_start; }
const double* weight_array_dbl() const { return m_weight_array_dbl; }
const int* weight_array_int() const { return m_weight_array_int; }
template<class FilterF> image_filter_lut(const FilterF& filter,
bool normalization=true)
{
calculate(filter, normalization);
}
protected:
void weight(unsigned idx, double val);
double calc_x(unsigned idx) const;
void normalize();
double radius() const { return m_radius; }
unsigned diameter() const { return m_diameter; }
int start() const { return m_start; }
const int16* weight_array() const { return &m_weight_array[0]; }
void normalize();
private:
image_filter_base(const image_filter_base&);
const image_filter_base& operator = (const image_filter_base&);
void realloc_lut(double radius);
image_filter_lut(const image_filter_lut&);
const image_filter_lut& operator = (const image_filter_lut&);
unsigned m_dimension;
int m_start;
double* m_weight_array_dbl;
int* m_weight_array_int;
double m_radius;
unsigned m_diameter;
int m_start;
pod_array<int16> m_weight_array;
};
//--------------------------------------------------------image_filter
template<class FilterF> class image_filter : public image_filter_base
template<class FilterF> class image_filter : public image_filter_lut
{
public:
image_filter() :
image_filter_base(FilterF::dimension()),
m_filter_function()
image_filter()
{
unsigned i;
unsigned dim = dimension() << image_subpixel_shift;
for(i = 0; i < dim; i++)
{
weight(i, m_filter_function.calc_weight(calc_x(i)));
}
normalize();
calculate(m_filter_function);
}
private:
FilterF m_filter_function;
@@ -101,19 +110,60 @@ namespace agg
//-----------------------------------------------image_filter_bilinear
class image_filter_bilinear
struct image_filter_bilinear
{
public:
static unsigned dimension() { return 2; }
static double radius() { return 1.0; }
static double calc_weight(double x)
{
return (x <= 0.0) ? x + 1.0 : 1.0 - x;
return 1.0 - x;
}
};
//-----------------------------------------------image_filter_hanning
struct image_filter_hanning
{
static double radius() { return 1.0; }
static double calc_weight(double x)
{
return 0.5 + 0.5 * cos(pi * x);
}
};
//-----------------------------------------------image_filter_hamming
struct image_filter_hamming
{
static double radius() { return 1.0; }
static double calc_weight(double x)
{
return 0.54 + 0.46 * cos(pi * x);
}
};
//-----------------------------------------------image_filter_hermite
struct image_filter_hermite
{
static double radius() { return 1.0; }
static double calc_weight(double x)
{
return (2.0 * x - 3.0) * x * x + 1.0;
}
};
//------------------------------------------------image_filter_quadric
struct image_filter_quadric
{
static double radius() { return 1.5; }
static double calc_weight(double x)
{
double t;
if(x < 0.5) return 0.75 - x * x;
if(x < 1.5) {t = x - 1.5; return 0.5 * t * t;}
return 0.0;
}
};
//------------------------------------------------image_filter_bicubic
class image_filter_bicubic
{
@@ -123,8 +173,7 @@ namespace agg
}
public:
static unsigned dimension() { return 4; }
static double radius() { return 2.0; }
static double calc_weight(double x)
{
return
@@ -133,17 +182,90 @@ namespace agg
}
};
//-------------------------------------------------image_filter_kaiser
class image_filter_kaiser
{
double a;
double i0a;
double epsilon;
public:
image_filter_kaiser(double b = 6.33) :
a(b), epsilon(1e-12)
{
i0a = 1.0 / bessel_i0(b);
}
static double radius() { return 1.0; }
double calc_weight(double x) const
{
return bessel_i0(a * sqrt(1. - x * x)) * i0a;
}
private:
double bessel_i0(double x) const
{
int i;
double sum, y, t;
sum = 1.;
y = x * x / 4.;
t = y;
for(i = 2; t > epsilon; i++)
{
sum += t;
t *= (double)y / (i * i);
}
return sum;
}
};
//----------------------------------------------image_filter_catrom
struct image_filter_catrom
{
static double radius() { return 2.0; }
static double calc_weight(double x)
{
if(x < 1.0) return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0));
if(x < 2.0) return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x)));
return 0.;
}
};
//---------------------------------------------image_filter_mitchell
class image_filter_mitchell
{
double p0, p2, p3;
double q0, q1, q2, q3;
public:
image_filter_mitchell(double b = 1.0/3.0, double c = 1.0/3.0) :
p0((6.0 - 2.0 * b) / 6.0),
p2((-18.0 + 12.0 * b + 6.0 * c) / 6.0),
p3((12.0 - 9.0 * b - 6.0 * c) / 6.0),
q0((8.0 * b + 24.0 * c) / 6.0),
q1((-12.0 * b - 48.0 * c) / 6.0),
q2((6.0 * b + 30.0 * c) / 6.0),
q3((-b - 6.0 * c) / 6.0)
{}
static double radius() { return 2.0; }
double calc_weight(double x) const
{
if(x < 1.0) return p0 + x * x * (p2 + x * p3);
if(x < 2.0) return q0 + x * (q1 + x * (q2 + x * q3));
return 0.0;
}
};
//----------------------------------------------image_filter_spline16
class image_filter_spline16
struct image_filter_spline16
{
public:
static unsigned dimension() { return 4; }
static double radius() { return 2.0; }
static double calc_weight(double x)
{
if(x < 0.0) x = -x;
if(x < 1.0)
{
return ((x - 9.0/5.0 ) * x - 1.0/5.0 ) * x + 1.0;
@@ -153,16 +275,12 @@ namespace agg
};
//---------------------------------------------image_filter_spline36
class image_filter_spline36
struct image_filter_spline36
{
public:
static unsigned dimension() { return 6; }
static double radius() { return 3.0; }
static double calc_weight(double x)
{
if(x < 0.0) x = -x;
if(x < 1.0)
{
return ((13.0/11.0 * x - 453.0/209.0) * x - 3.0/209.0) * x + 1.0;
@@ -171,195 +289,158 @@ namespace agg
{
return ((-6.0/11.0 * (x-1) + 270.0/209.0) * (x-1) - 156.0/ 209.0) * (x-1);
}
return ((1.0/11.0 * (x-2) - 45.0/209.0) * (x-2) + 26.0/209.0) * (x-2);
}
};
//-----------------------------------------------image_filter_sinc36
class image_filter_sinc36
//----------------------------------------------image_filter_gaussian
struct image_filter_gaussian
{
public:
static unsigned dimension() { return 6; }
static double calc_weight(double x)
static double radius() { return 2.0; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x3 = x * (1.0/3.0);
return (sin(x) / x) * (sin(x3) / x3);
return exp(-2.0 * x * x) * sqrt(2.0 / pi);
}
};
//------------------------------------------------image_filter_bessel
struct image_filter_bessel
{
static double radius() { return 3.2383; }
static double calc_weight(double x)
{
return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x);
}
};
//-------------------------------------------------image_filter_sinc
class image_filter_sinc
{
public:
image_filter_sinc(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
double radius() const { return m_radius; }
double calc_weight(double x) const
{
if(x == 0.0) return 1.0;
x *= pi;
return sin(x) / x;
}
private:
double m_radius;
};
//-----------------------------------------------image_filter_lanczos
class image_filter_lanczos
{
public:
image_filter_lanczos(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
double radius() const { return m_radius; }
double calc_weight(double x) const
{
if(x == 0.0) return 1.0;
if(x > m_radius) return 0.0;
x *= pi;
double xr = x / m_radius;
return (sin(x) / x) * (sin(xr) / xr);
}
private:
double m_radius;
};
//----------------------------------------------image_filter_blackman
class image_filter_blackman
{
public:
image_filter_blackman(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
double radius() const { return m_radius; }
double calc_weight(double x) const
{
if(x == 0.0) return 1.0;
if(x > m_radius) return 0.0;
x *= pi;
double xr = x / m_radius;
return (sin(x) / x) * (0.42 + 0.5*cos(xr) + 0.08*cos(2*xr));
}
private:
double m_radius;
};
//------------------------------------------------image_filter_sinc36
class image_filter_sinc36 : public image_filter_sinc
{ public: image_filter_sinc36() : image_filter_sinc(3.0){} };
//------------------------------------------------image_filter_sinc64
class image_filter_sinc64
{
public:
static unsigned dimension() { return 8; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x4 = x * 0.25;
return (sin(x) / x) * (sin(x4) / x4);
}
};
class image_filter_sinc64 : public image_filter_sinc
{ public: image_filter_sinc64() : image_filter_sinc(4.0){} };
//-----------------------------------------------image_filter_sinc100
class image_filter_sinc100
{
public:
static unsigned dimension() { return 10; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x5 = x * 0.2;
return (sin(x) / x) * (sin(x5) / x5);
}
};
class image_filter_sinc100 : public image_filter_sinc
{ public: image_filter_sinc100() : image_filter_sinc(5.0){} };
//-----------------------------------------------image_filter_sinc144
class image_filter_sinc144
{
public:
static unsigned dimension() { return 12; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x6 = x * (1.0/6.0);
return (sin(x) / x) * (sin(x6) / x6);
}
};
class image_filter_sinc144 : public image_filter_sinc
{ public: image_filter_sinc144() : image_filter_sinc(6.0){} };
//-----------------------------------------------image_filter_sinc196
class image_filter_sinc196
{
public:
static unsigned dimension() { return 14; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x7 = x * (1.0/7.0);
return (sin(x) / x) * (sin(x7) / x7);
}
};
class image_filter_sinc196 : public image_filter_sinc
{ public: image_filter_sinc196() : image_filter_sinc(7.0){} };
//-----------------------------------------------image_filter_sinc256
class image_filter_sinc256
{
public:
static unsigned dimension() { return 16; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x8 = x * 0.125;
return (sin(x) / x) * (sin(x8) / x8);
}
};
class image_filter_sinc256 : public image_filter_sinc
{ public: image_filter_sinc256() : image_filter_sinc(8.0){} };
//---------------------------------------------image_filter_lanczos36
class image_filter_lanczos36 : public image_filter_lanczos
{ public: image_filter_lanczos36() : image_filter_lanczos(3.0){} };
//---------------------------------------------image_filter_lanczos64
class image_filter_lanczos64 : public image_filter_lanczos
{ public: image_filter_lanczos64() : image_filter_lanczos(4.0){} };
//--------------------------------------------image_filter_lanczos100
class image_filter_lanczos100 : public image_filter_lanczos
{ public: image_filter_lanczos100() : image_filter_lanczos(5.0){} };
//--------------------------------------------image_filter_lanczos144
class image_filter_lanczos144 : public image_filter_lanczos
{ public: image_filter_lanczos144() : image_filter_lanczos(6.0){} };
//--------------------------------------------image_filter_lanczos196
class image_filter_lanczos196 : public image_filter_lanczos
{ public: image_filter_lanczos196() : image_filter_lanczos(7.0){} };
//--------------------------------------------image_filter_lanczos256
class image_filter_lanczos256 : public image_filter_lanczos
{ public: image_filter_lanczos256() : image_filter_lanczos(8.0){} };
//--------------------------------------------image_filter_blackman36
class image_filter_blackman36
{
public:
static unsigned dimension() { return 6; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x3 = x * (1.0/3.0);
return (sin(x) / x) * (0.42 + 0.5*cos(x3) + 0.08*cos(2*x3));
}
};
class image_filter_blackman36 : public image_filter_blackman
{ public: image_filter_blackman36() : image_filter_blackman(3.0){} };
//--------------------------------------------image_filter_blackman64
class image_filter_blackman64
{
public:
static unsigned dimension() { return 8; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x4 = x * 0.25;
return (sin(x) / x) * (0.42 + 0.5*cos(x4) + 0.08*cos(2*x4));
}
};
class image_filter_blackman64 : public image_filter_blackman
{ public: image_filter_blackman64() : image_filter_blackman(4.0){} };
//-------------------------------------------image_filter_blackman100
class image_filter_blackman100
{
public:
static unsigned dimension() { return 10; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x5 = x * 0.2;
return (sin(x) / x) * (0.42 + 0.5*cos(x5) + 0.08*cos(2*x5));
}
};
class image_filter_blackman100 : public image_filter_blackman
{ public: image_filter_blackman100() : image_filter_blackman(5.0){} };
//-------------------------------------------image_filter_blackman144
class image_filter_blackman144
{
public:
static unsigned dimension() { return 12; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x6 = x * (1.0/6.0);
return (sin(x) / x) * (0.42 + 0.5*cos(x6) + 0.08*cos(2*x6));
}
};
class image_filter_blackman144 : public image_filter_blackman
{ public: image_filter_blackman144() : image_filter_blackman(6.0){} };
//-------------------------------------------image_filter_blackman196
class image_filter_blackman196
{
public:
static unsigned dimension() { return 14; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x7 = x * (1.0/7.0);
return (sin(x) / x) * (0.42 + 0.5*cos(x7) + 0.08*cos(2*x7));
}
};
class image_filter_blackman196 : public image_filter_blackman
{ public: image_filter_blackman196() : image_filter_blackman(7.0){} };
//-------------------------------------------image_filter_blackman256
class image_filter_blackman256
{
public:
static unsigned dimension() { return 16; }
static double calc_weight(double x)
{
if(x == 0.0) return 1.0;
x *= pi;
double x8 = x * 0.125;
return (sin(x) / x) * (0.42 + 0.5*cos(x8) + 0.08*cos(2*x8));
}
};
class image_filter_blackman256 : public image_filter_blackman
{ public: image_filter_blackman256() : image_filter_blackman(8.0){} };
}
+83 -17
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -24,44 +24,58 @@ namespace agg
// See Implementation agg_line_aa_basics.cpp
//-------------------------------------------------------------------------
enum
enum line_subpixel_scale_e
{
line_subpixel_shift = 8, //----line_subpixel_shift
line_subpixel_size = 1 << line_subpixel_shift, //----line_subpixel_size
line_subpixel_mask = line_subpixel_size - 1 //----line_subpixel_mask
line_subpixel_shift = 8, //----line_subpixel_shift
line_subpixel_scale = 1 << line_subpixel_shift, //----line_subpixel_scale
line_subpixel_mask = line_subpixel_scale - 1, //----line_subpixel_mask
line_max_coord = (1 << 28) - 1, //----line_max_coord
line_max_length = 1 << (line_subpixel_shift + 10) //----line_max_length
};
//-------------------------------------------------------------------------
enum
enum line_mr_subpixel_scale_e
{
line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift
line_mr_subpixel_size = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_size
line_mr_subpixel_mask = line_mr_subpixel_size - 1 //----line_mr_subpixel_mask
line_mr_subpixel_scale = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_scale
line_mr_subpixel_mask = line_mr_subpixel_scale - 1 //----line_mr_subpixel_mask
};
//------------------------------------------------------------------line_mr
inline int line_mr(int x)
AGG_INLINE int line_mr(int x)
{
return x >> (line_subpixel_shift - line_mr_subpixel_shift);
}
//-------------------------------------------------------------------line_hr
inline int line_hr(int x)
AGG_INLINE int line_hr(int x)
{
return x << (line_subpixel_shift - line_mr_subpixel_shift);
}
//---------------------------------------------------------------line_dbl_hr
inline int line_dbl_hr(int x)
AGG_INLINE int line_dbl_hr(int x)
{
return x << line_subpixel_shift;
}
//---------------------------------------------------------------line_coord
inline int line_coord(double x)
struct line_coord
{
return int(x * line_subpixel_size);
}
AGG_INLINE static int conv(double x)
{
return iround(x * line_subpixel_scale);
}
};
//-----------------------------------------------------------line_coord_sat
struct line_coord_sat
{
AGG_INLINE static int conv(double x)
{
return saturation<line_max_coord>::iround(x * line_subpixel_scale);
}
};
//==========================================================line_parameters
struct line_parameters
@@ -96,6 +110,29 @@ namespace agg
{
return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
}
//---------------------------------------------------------------------
void divide(line_parameters& lp1, line_parameters& lp2) const
{
int xmid = (x1 + x2) >> 1;
int ymid = (y1 + y2) >> 1;
int len2 = len >> 1;
lp1 = *this;
lp2 = *this;
lp1.x2 = xmid;
lp1.y2 = ymid;
lp1.len = len2;
lp1.dx = abs(lp1.x2 - lp1.x1);
lp1.dy = abs(lp1.y2 - lp1.y1);
lp2.x1 = xmid;
lp2.y1 = ymid;
lp2.len = len2;
lp2.dx = abs(lp2.x2 - lp2.x1);
lp2.dy = abs(lp2.y2 - lp2.y1);
}
//---------------------------------------------------------------------
int x1, y1, x2, y2, dx, dy, sx, sy;
@@ -105,8 +142,8 @@ namespace agg
int octant;
//---------------------------------------------------------------------
static int8u s_orthogonal_quadrant[8];
static int8u s_diagonal_quadrant[8];
static const int8u s_orthogonal_quadrant[8];
static const int8u s_diagonal_quadrant[8];
};
@@ -118,6 +155,35 @@ namespace agg
const line_parameters& l2,
int* x, int* y);
//-------------------------------------------fix_degenerate_bisectrix_start
void inline fix_degenerate_bisectrix_start(const line_parameters& lp,
int* x, int* y)
{
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
if(d < line_subpixel_scale/2)
{
*x = lp.x1 + (lp.y2 - lp.y1);
*y = lp.y1 - (lp.x2 - lp.x1);
}
}
//---------------------------------------------fix_degenerate_bisectrix_end
void inline fix_degenerate_bisectrix_end(const line_parameters& lp,
int* x, int* y)
{
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
if(d < line_subpixel_scale/2)
{
*x = lp.x2 + (lp.y2 - lp.y1);
*y = lp.y2 - (lp.x2 - lp.x1);
}
}
}
#endif
+237 -47
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -12,6 +12,9 @@
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
// Bessel function (besj) was adapted for use in AGG library by Andy Wilk
// Contact: [email protected]
//----------------------------------------------------------------------------
#ifndef AGG_MATH_INCLUDED
#define AGG_MATH_INCLUDED
@@ -22,54 +25,117 @@
namespace agg
{
const double intersection_epsilon = 1.0e-8;
//------------------------------------------------------vertex_dist_epsilon
// Coinciding points maximal distance (Epsilon)
const double vertex_dist_epsilon = 1e-14;
//------------------------------------------------------calc_point_location
inline double calc_point_location(double x1, double y1,
double x2, double y2,
double x, double y)
//-----------------------------------------------------intersection_epsilon
// See calc_intersection
const double intersection_epsilon = 1.0e-30;
//------------------------------------------------------------cross_product
AGG_INLINE double cross_product(double x1, double y1,
double x2, double y2,
double x, double y)
{
return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
}
//--------------------------------------------------------point_in_triangle
inline bool point_in_triangle(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x, double y)
AGG_INLINE bool point_in_triangle(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x, double y)
{
bool cp1 = calc_point_location(x1, y1, x2, y2, x, y) < 0.0;
bool cp2 = calc_point_location(x2, y2, x3, y3, x, y) < 0.0;
bool cp3 = calc_point_location(x3, y3, x1, y1, x, y) < 0.0;
bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0;
bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0;
bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0;
return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
}
//-----------------------------------------------------------calc_distance
inline double calc_distance(double x1, double y1, double x2, double y2)
AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2)
{
double dx = x2-x1;
double dy = y2-y1;
return sqrt(dx * dx + dy * dy);
}
//------------------------------------------------calc_point_line_distance
inline double calc_point_line_distance(double x1, double y1,
double x2, double y2,
double x, double y)
//--------------------------------------------------------calc_sq_distance
AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
{
double dx = x2-x1;
double dy = y2-y1;
return ((x - x2) * dy - (y - y2) * dx) / sqrt(dx * dx + dy * dy);
return dx * dx + dy * dy;
}
//------------------------------------------------calc_line_point_distance
AGG_INLINE double calc_line_point_distance(double x1, double y1,
double x2, double y2,
double x, double y)
{
double dx = x2-x1;
double dy = y2-y1;
double d = sqrt(dx * dx + dy * dy);
if(d < vertex_dist_epsilon)
{
return calc_distance(x1, y1, x, y);
}
return ((x - x2) * dy - (y - y2) * dx) / d;
}
//-------------------------------------------------------calc_line_point_u
AGG_INLINE double calc_segment_point_u(double x1, double y1,
double x2, double y2,
double x, double y)
{
double dx = x2 - x1;
double dy = y2 - y1;
if(dx == 0 && dy == 0)
{
return 0;
}
double pdx = x - x1;
double pdy = y - y1;
return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
}
//---------------------------------------------calc_line_point_sq_distance
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
double x2, double y2,
double x, double y,
double u)
{
if(u <= 0)
{
return calc_sq_distance(x, y, x1, y1);
}
else
if(u >= 1)
{
return calc_sq_distance(x, y, x2, y2);
}
return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
}
//---------------------------------------------calc_line_point_sq_distance
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
double x2, double y2,
double x, double y)
{
return
calc_segment_point_sq_distance(
x1, y1, x2, y2, x, y,
calc_segment_point_u(x1, y1, x2, y2, x, y));
}
//-------------------------------------------------------calc_intersection
inline bool calc_intersection(double ax, double ay, double bx, double by,
double cx, double cy, double dx, double dy,
double* x, double* y)
AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by,
double cx, double cy, double dx, double dy,
double* x, double* y)
{
double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy);
double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx);
@@ -80,27 +146,52 @@ namespace agg
return true;
}
//-----------------------------------------------------intersection_exists
AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2,
double x3, double y3, double x4, double y4)
{
// It's less expensive but you can't control the
// boundary conditions: Less or LessEqual
double dx1 = x2 - x1;
double dy1 = y2 - y1;
double dx2 = x4 - x3;
double dy2 = y4 - y3;
return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) !=
((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) !=
((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
// It's is more expensive but more flexible
// in terms of boundary conditions.
//--------------------
//double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
//if(fabs(den) < intersection_epsilon) return false;
//double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3);
//double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3);
//double ua = nom1 / den;
//double ub = nom2 / den;
//return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0;
}
//--------------------------------------------------------calc_orthogonal
inline void calc_orthogonal(double thickness,
double x1, double y1,
double x2, double y2,
double* x, double* y)
AGG_INLINE void calc_orthogonal(double thickness,
double x1, double y1,
double x2, double y2,
double* x, double* y)
{
double dx = x2 - x1;
double dy = y2 - y1;
double d = sqrt(dx*dx + dy*dy);
*x = thickness * dy / d;
*y = thickness * dx / d;
*x = thickness * dy / d;
*y = -thickness * dx / d;
}
//--------------------------------------------------------dilate_triangle
inline void dilate_triangle(double x1, double y1,
double x2, double y2,
double x3, double y3,
double *x, double* y,
double d)
AGG_INLINE void dilate_triangle(double x1, double y1,
double x2, double y2,
double x3, double y3,
double *x, double* y,
double d)
{
double dx1=0.0;
double dy1=0.0;
@@ -108,10 +199,10 @@ namespace agg
double dy2=0.0;
double dx3=0.0;
double dy3=0.0;
double loc = calc_point_location(x1, y1, x2, y2, x3, y3);
double loc = cross_product(x1, y1, x2, y2, x3, y3);
if(fabs(loc) > intersection_epsilon)
{
if(calc_point_location(x1, y1, x2, y2, x3, y3) > 0.0)
if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
{
d = -d;
}
@@ -119,12 +210,20 @@ namespace agg
calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
}
*x++ = x1 + dx1; *y++ = y1 - dy1;
*x++ = x2 + dx1; *y++ = y2 - dy1;
*x++ = x2 + dx2; *y++ = y2 - dy2;
*x++ = x3 + dx2; *y++ = y3 - dy2;
*x++ = x3 + dx3; *y++ = y3 - dy3;
*x++ = x1 + dx3; *y++ = y1 - dy3;
*x++ = x1 + dx1; *y++ = y1 + dy1;
*x++ = x2 + dx1; *y++ = y2 + dy1;
*x++ = x2 + dx2; *y++ = y2 + dy2;
*x++ = x3 + dx2; *y++ = y3 + dy2;
*x++ = x3 + dx3; *y++ = y3 + dy3;
*x++ = x1 + dx3; *y++ = y1 + dy3;
}
//------------------------------------------------------calc_triangle_area
AGG_INLINE double calc_triangle_area(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5;
}
//-------------------------------------------------------calc_polygon_area
@@ -159,7 +258,7 @@ namespace agg
#pragma warning(push)
#pragma warning(disable : 4035) //Disable warning "no return value"
#endif
inline unsigned fast_sqrt(unsigned val)
AGG_INLINE unsigned fast_sqrt(unsigned val)
{
#if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM)
//For Ix86 family processors this assembler code is used.
@@ -241,6 +340,97 @@ namespace agg
//--------------------------------------------------------------------besj
// Function BESJ calculates Bessel function of first kind of order n
// Arguments:
// n - an integer (>=0), the order
// x - value at which the Bessel function is required
//--------------------
// C++ Mathematical Library
// Convereted from equivalent FORTRAN library
// Converetd by Gareth Walker for use by course 392 computational project
// All functions tested and yield the same results as the corresponding
// FORTRAN versions.
//
// If you have any problems using these functions please report them to
// [email protected]
//
// Documentation available on the web
// http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html
// Version 1.0 8/98
// 29 October, 1999
//--------------------
// Adapted for use in AGG library by Andy Wilk ([email protected])
//------------------------------------------------------------------------
inline double besj(double x, int n)
{
if(n < 0)
{
return 0;
}
double d = 1E-6;
double b = 0;
if(fabs(x) <= d)
{
if(n != 0) return 0;
return 1;
}
double b1 = 0; // b1 is the value from the previous iteration
// Set up a starting order for recurrence
int m1 = (int)fabs(x) + 6;
if(fabs(x) > 5)
{
m1 = (int)(fabs(1.4 * x + 60 / x));
}
int m2 = (int)(n + 2 + fabs(x) / 4);
if (m1 > m2)
{
m2 = m1;
}
// Apply recurrence down from curent max order
for(;;)
{
double c3 = 0;
double c2 = 1E-30;
double c4 = 0;
int m8 = 1;
if (m2 / 2 * 2 == m2)
{
m8 = -1;
}
int imax = m2 - 2;
for (int i = 1; i <= imax; i++)
{
double c6 = 2 * (m2 - i) * c2 / x - c3;
c3 = c2;
c2 = c6;
if(m2 - i - 1 == n)
{
b = c6;
}
m8 = -1 * m8;
if (m8 > 0)
{
c4 = c4 + 2 * c6;
}
}
double c6 = 2 * c2 / x - c3;
if(n == 0)
{
b = c6;
}
c4 += c6;
b /= c4;
if(fabs(b - b1) < d)
{
return b;
}
b1 = b;
m2 += 3;
}
}
}
+354 -205
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -36,297 +36,446 @@ namespace agg
//------------------------------------------------------------line_join_e
enum line_join_e
{
miter_join,
miter_join_revert,
round_join,
bevel_join
miter_join = 0,
miter_join_revert = 1,
round_join = 2,
bevel_join = 3,
miter_join_round = 4
};
// Minimal angle to calculate round joins, less than 0.1 degree.
const double stroke_theta = 0.001; //----stroke_theta
//--------------------------------------------------------stroke_calc_arc
template<class VertexConsumer>
void stroke_calc_arc(VertexConsumer& out_vertices,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double width,
double approximation_scale)
//-----------------------------------------------------------inner_join_e
enum inner_join_e
{
inner_bevel,
inner_miter,
inner_jag,
inner_round
};
//------------------------------------------------------------math_stroke
template<class VertexConsumer> class math_stroke
{
public:
typedef typename VertexConsumer::value_type coord_type;
// Check if we actually need the arc
//-----------------
double dd = calc_distance(dx1, dy1, dx2, dy2);
if(dd < approximation_scale)
math_stroke();
void line_cap(line_cap_e lc) { m_line_cap = lc; }
void line_join(line_join_e lj) { m_line_join = lj; }
void inner_join(inner_join_e ij) { m_inner_join = ij; }
line_cap_e line_cap() const { return m_line_cap; }
line_join_e line_join() const { return m_line_join; }
inner_join_e inner_join() const { return m_inner_join; }
void width(double w);
void miter_limit(double ml) { m_miter_limit = ml; }
void miter_limit_theta(double t);
void inner_miter_limit(double ml) { m_inner_miter_limit = ml; }
void approximation_scale(double as) { m_approx_scale = as; }
double width() const { return m_width * 2.0; }
double miter_limit() const { return m_miter_limit; }
double inner_miter_limit() const { return m_inner_miter_limit; }
double approximation_scale() const { return m_approx_scale; }
void calc_cap(VertexConsumer& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
double len);
void calc_join(VertexConsumer& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double len1,
double len2);
private:
void calc_arc(VertexConsumer& out_vertices,
double x, double y,
double dx1, double dy1,
double dx2, double dy2);
void calc_miter(VertexConsumer& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double dx1, double dy1,
double dx2, double dy2,
line_join_e lj,
double ml);
double m_width;
double m_width_abs;
int m_width_sign;
double m_miter_limit;
double m_inner_miter_limit;
double m_approx_scale;
line_cap_e m_line_cap;
line_join_e m_line_join;
inner_join_e m_inner_join;
};
//-----------------------------------------------------------------------
template<class VC> math_stroke<VC>::math_stroke() :
m_width(0.5),
m_width_abs(0.5),
m_width_sign(1),
m_miter_limit(4.0),
m_inner_miter_limit(1.01),
m_approx_scale(1.0),
m_line_cap(butt_cap),
m_line_join(miter_join),
m_inner_join(inner_miter)
{
}
//-----------------------------------------------------------------------
template<class VC> void math_stroke<VC>::width(double w)
{
m_width = w * 0.5;
if(m_width < 0)
{
out_vertices.add(coord_type(x + dx1, y + dy1));
if(dd > approximation_scale * 0.25)
{
out_vertices.add(coord_type(x + dx2, y + dy2));
}
return;
m_width_abs = -m_width;
m_width_sign = -1;
}
else
{
m_width_abs = m_width;
m_width_sign = 1;
}
}
double a1 = atan2(dy1, dx1);
double a2 = atan2(dy2, dx2);
//-----------------------------------------------------------------------
template<class VC> void math_stroke<VC>::miter_limit_theta(double t)
{
m_miter_limit = 1.0 / sin(t * 0.5) ;
}
//-----------------------------------------------------------------------
template<class VC>
void math_stroke<VC>::calc_arc(VC& out_vertices,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
double a1 = atan2(dy1 * m_width_sign, dx1 * m_width_sign);
double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign);
double da = a1 - a2;
int i, n;
//if(fabs(da) < stroke_theta)
//{
// out_vertices.add(coord_type(x + dx1, y + dy1));
// //out_vertices.add(coord_type(x + dx2, y + dy2));
// return;
//}
da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
bool ccw = da > 0.0 && da < pi;
if(width < 0) width = -width;
da = fabs(1.0 / (width * approximation_scale));
if(!ccw)
out_vertices.add(coord_type(x + dx1, y + dy1));
if(m_width_sign > 0)
{
if(a1 > a2) a2 += 2 * pi;
while(a1 < a2)
n = int((a2 - a1) / da);
da = (a2 - a1) / (n + 1);
a1 += da;
for(i = 0; i < n; i++)
{
out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width));
out_vertices.add(coord_type(x + cos(a1) * m_width,
y + sin(a1) * m_width));
a1 += da;
}
}
else
{
if(a1 < a2) a2 -= 2 * pi;
while(a1 > a2)
n = int((a1 - a2) / da);
da = (a1 - a2) / (n + 1);
a1 -= da;
for(i = 0; i < n; i++)
{
out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width));
out_vertices.add(coord_type(x + cos(a1) * m_width,
y + sin(a1) * m_width));
a1 -= da;
}
}
out_vertices.add(coord_type(x + dx2, y + dy2));
}
//-------------------------------------------------------stroke_calc_miter
template<class VertexConsumer>
void stroke_calc_miter(VertexConsumer& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double dx1, double dy1,
double dx2, double dy2,
double width,
bool revert_flag,
double miter_limit)
//-----------------------------------------------------------------------
template<class VC>
void math_stroke<VC>::calc_miter(VC& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double dx1, double dy1,
double dx2, double dy2,
line_join_e lj,
double ml)
{
typedef typename VertexConsumer::value_type coord_type;
double xi = v1.x;
double yi = v1.y;
bool miter_limit_exceeded = true; // Assume the worst
if(!calc_intersection(v0.x + dx1, v0.y - dy1,
v1.x + dx1, v1.y - dy1,
v1.x + dx2, v1.y - dy2,
v2.x + dx2, v2.y - dy2,
&xi, &yi))
if(calc_intersection(v0.x + dx1, v0.y - dy1,
v1.x + dx1, v1.y - dy1,
v1.x + dx2, v1.y - dy2,
v2.x + dx2, v2.y - dy2,
&xi, &yi))
{
// The calculation didn't succeed, most probaly
// the three points lie one straight line
// Calculation of the intersection succeeded
//---------------------
double d1 = calc_distance(v1.x, v1.y, xi, yi);
double lim = m_width_abs * ml;
if(d1 <= lim)
{
// Inside the miter limit
//---------------------
out_vertices.add(coord_type(xi, yi));
miter_limit_exceeded = false;
}
}
else
{
// Calculation of the intersection failed, most probably
// the three points lie one straight line.
// First check if v0 and v2 lie on the opposite sides of vector:
// (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
// to the line determined by vertices v0 and v1.
// This condition determines whether the next line segments continues
// the previous one or goes back.
//----------------
if(calc_distance(dx1, -dy1, dx2, -dy2) < width * 0.025)
double x2 = v1.x + dx1;
double y2 = v1.y - dy1;
if(((x2 - v0.x)*dy1 - (v0.y - y2)*dx1 < 0.0) !=
((x2 - v2.x)*dy1 - (v2.y - y2)*dx1 < 0.0))
{
// This case means that the next segment continues
// the previous one (straight line)
//-----------------
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
}
else
{
// This case means that the next segment goes back
//-----------------
if(revert_flag)
{
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
}
else
{
// If no miter-revert, calcuate new dx1, dy1, dx2, dy2
out_vertices.add(coord_type(v1.x + dx1 + dy1 * miter_limit,
v1.y - dy1 + dx1 * miter_limit));
out_vertices.add(coord_type(v1.x + dx2 - dy2 * miter_limit,
v1.y - dy2 - dx2 * miter_limit));
}
miter_limit_exceeded = false;
}
}
else
{
double d1 = calc_distance(v1.x, v1.y, xi, yi);
double lim = width * miter_limit;
if(d1 > lim)
{
// Miter limit exceeded
//------------------------
if(revert_flag)
{
// For the compatibility with SVG, PDF, etc,
// we use a simple bevel join instead of
// "smart" bevel
//-------------------
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
}
else
{
// Smart bevel that cuts the miter at the limit point
//-------------------
d1 = lim / d1;
double x1 = v1.x + dx1;
double y1 = v1.y - dy1;
double x2 = v1.x + dx2;
double y2 = v1.y - dy2;
x1 += (xi - x1) * d1;
y1 += (yi - y1) * d1;
x2 += (xi - x2) * d1;
y2 += (yi - y2) * d1;
out_vertices.add(coord_type(x1, y1));
out_vertices.add(coord_type(x2, y2));
}
}
else
if(miter_limit_exceeded)
{
// Miter limit exceeded
//------------------------
switch(lj)
{
// Inside the miter limit
//---------------------
out_vertices.add(coord_type(xi, yi));
case miter_join_revert:
// For the compatibility with SVG, PDF, etc,
// we use a simple bevel join instead of
// "smart" bevel
//-------------------
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
break;
case miter_join_round:
calc_arc(out_vertices, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
break;
default:
// If no miter-revert, calculate new dx1, dy1, dx2, dy2
//----------------
ml *= m_width_sign;
out_vertices.add(coord_type(v1.x + dx1 + dy1 * ml,
v1.y - dy1 + dx1 * ml));
out_vertices.add(coord_type(v1.x + dx2 - dy2 * ml,
v1.y - dy2 - dx2 * ml));
break;
}
}
}
//--------------------------------------------------------stroke_calc_cap
template<class VertexConsumer>
void stroke_calc_cap(VertexConsumer& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
double len,
line_cap_e line_cap,
double width,
double approximation_scale)
template<class VC>
void math_stroke<VC>::calc_cap(VC& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
double len)
{
typedef typename VertexConsumer::value_type coord_type;
out_vertices.remove_all();
double dx1 = width * (v1.y - v0.y) / len;
double dy1 = width * (v1.x - v0.x) / len;
double dx1 = (v1.y - v0.y) / len;
double dy1 = (v1.x - v0.x) / len;
double dx2 = 0;
double dy2 = 0;
if(line_cap == square_cap)
{
dx2 = dy1;
dy2 = dx1;
}
dx1 *= m_width;
dy1 *= m_width;
if(line_cap == round_cap)
if(m_line_cap != round_cap)
{
double a1 = atan2(dy1, -dx1);
double a2 = a1 + pi;
double da = fabs(1.0 / (width * approximation_scale));
while(a1 < a2)
if(m_line_cap == square_cap)
{
out_vertices.add(coord_type(v0.x + cos(a1) * width,
v0.y + sin(a1) * width));
a1 += da;
dx2 = dy1 * m_width_sign;
dy2 = dx1 * m_width_sign;
}
out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1));
}
else
{
out_vertices.add(coord_type(v0.x - dx1 - dx2, v0.y + dy1 - dy2));
out_vertices.add(coord_type(v0.x + dx1 - dx2, v0.y - dy1 - dy2));
}
else
{
double da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
double a1;
int i;
int n = int(pi / da);
da = pi / (n + 1);
out_vertices.add(coord_type(v0.x - dx1, v0.y + dy1));
if(m_width_sign > 0)
{
a1 = atan2(dy1, -dx1);
a1 += da;
for(i = 0; i < n; i++)
{
out_vertices.add(coord_type(v0.x + cos(a1) * m_width,
v0.y + sin(a1) * m_width));
a1 += da;
}
}
else
{
a1 = atan2(-dy1, dx1);
a1 -= da;
for(i = 0; i < n; i++)
{
out_vertices.add(coord_type(v0.x + cos(a1) * m_width,
v0.y + sin(a1) * m_width));
a1 -= da;
}
}
out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1));
}
}
//-------------------------------------------------------stroke_calc_join
template<class VertexConsumer>
void stroke_calc_join(VertexConsumer& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double len1,
double len2,
double width,
line_join_e line_join,
line_join_e inner_line_join,
double miter_limit,
double inner_miter_limit,
double approximation_scale)
//-----------------------------------------------------------------------
template<class VC>
void math_stroke<VC>::calc_join(VC& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double len1,
double len2)
{
typedef typename VertexConsumer::value_type coord_type;
double dx1, dy1, dx2, dy2;
double d;
dx1 = width * (v1.y - v0.y) / len1;
dy1 = width * (v1.x - v0.x) / len1;
dx1 = m_width * (v1.y - v0.y) / len1;
dy1 = m_width * (v1.x - v0.x) / len1;
dx2 = width * (v2.y - v1.y) / len2;
dy2 = width * (v2.x - v1.x) / len2;
dx2 = m_width * (v2.y - v1.y) / len2;
dy2 = m_width * (v2.x - v1.x) / len2;
out_vertices.remove_all();
if(calc_point_location(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y) > 0.0)
double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
if(cp != 0 && (cp > 0) == (m_width > 0))
{
// Inner join
//---------------
stroke_calc_miter(out_vertices,
v0, v1, v2, dx1, dy1, dx2, dy2,
width,
inner_line_join == miter_join_revert,
inner_miter_limit);
double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
if(limit < m_inner_miter_limit)
{
limit = m_inner_miter_limit;
}
switch(m_inner_join)
{
default: // inner_bevel
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
break;
case inner_miter:
calc_miter(out_vertices,
v0, v1, v2, dx1, dy1, dx2, dy2,
miter_join_revert,
limit);
break;
case inner_jag:
case inner_round:
{
d = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
if(d < len1 * len1 && d < len2 * len2)
{
calc_miter(out_vertices,
v0, v1, v2, dx1, dy1, dx2, dy2,
miter_join_revert,
limit);
}
else
{
if(m_inner_join == inner_jag)
{
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
out_vertices.add(coord_type(v1.x, v1.y ));
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
}
else
{
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
out_vertices.add(coord_type(v1.x, v1.y ));
calc_arc(out_vertices, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
out_vertices.add(coord_type(v1.x, v1.y ));
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
}
}
}
break;
}
}
else
{
// Outer join
//---------------
switch(line_join)
line_join_e lj = m_line_join;
if(m_line_join == round_join || m_line_join == bevel_join)
{
// This is an optimization that reduces the number of points
// in cases of almost collonear segments. If there's no
// visible difference between bevel and miter joins we'd rather
// use miter join because it adds only one point instead of two.
//
// Here we calculate the middle point between the bevel points
// and then, the distance between v1 and this middle point.
// At outer joins this distance always less than stroke width,
// because it's actually the height of an isosceles triangle of
// v1 and its two bevel points. If the difference between this
// width and this value is small (no visible bevel) we can switch
// to the miter join.
//
// The constant in the expression makes the result approximately
// the same as in round joins and caps. One can safely comment
// out this "if".
//-------------------
double dx = (dx1 + dx2) / 2;
double dy = (dy1 + dy2) / 2;
d = m_width_abs - sqrt(dx * dx + dy * dy);
if(d < 0.0625 / m_approx_scale)
{
lj = miter_join;
}
}
switch(lj)
{
case miter_join:
stroke_calc_miter(out_vertices,
v0, v1, v2, dx1, dy1, dx2, dy2,
width,
false,
miter_limit);
break;
case miter_join_revert:
stroke_calc_miter(out_vertices,
v0, v1, v2, dx1, dy1, dx2, dy2,
width,
true,
miter_limit);
case miter_join_round:
calc_miter(out_vertices,
v0, v1, v2, dx1, dy1, dx2, dy2,
lj,
m_miter_limit);
break;
case round_join:
stroke_calc_arc(out_vertices,
v1.x, v1.y, dx1, -dy1, dx2, -dy2,
width, approximation_scale);
calc_arc(out_vertices, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
break;
default: // Bevel join
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
if(calc_distance(dx1, dy1, dx2, dy2) > approximation_scale * 0.25)
{
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
}
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
break;
}
}
+65
View File
@@ -0,0 +1,65 @@
//----------------------------------------------------------------------------
// 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PATH_LENGTH_INCLUDED
#define AGG_PATH_LENGTH_INCLUDED
#include "agg_math.h"
namespace agg
{
template<class VertexSource>
double path_length(VertexSource& vs, unsigned path_id = 0)
{
double len = 0.0;
double start_x = 0.0;
double start_y = 0.0;
double x1 = 0.0;
double y1 = 0.0;
double x2 = 0.0;
double y2 = 0.0;
bool first = true;
unsigned cmd;
vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x2, &y2)))
{
if(is_vertex(cmd))
{
if(first || is_move_to(cmd))
{
start_x = x2;
start_y = y2;
}
else
{
len += calc_distance(x1, y1, x2, y2);
}
x1 = x2;
y1 = y2;
first = false;
}
else
{
if(is_close(cmd) && !first)
{
len += calc_distance(x1, y1, start_x, start_y);
}
}
}
return len;
}
}
#endif
File diff suppressed because it is too large Load Diff
+12 -17
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -21,7 +21,6 @@
namespace agg
{
//---------------------------------------------------------vertex_integer
template<class T, unsigned CoordShift=6> struct vertex_integer
{
@@ -33,10 +32,10 @@ namespace agg
cmd_curve4 = 3
};
enum
enum coord_scale_e
{
coord_shift = CoordShift,
coord_mult = 1 << coord_shift
coord_scale = 1 << coord_shift
};
T x,y;
@@ -49,8 +48,8 @@ namespace agg
double dx=0, double dy=0,
double scale=1.0) const
{
*x_ = dx + (double(x >> 1) / coord_mult) * scale;
*y_ = dy + (double(y >> 1) / coord_mult) * scale;
*x_ = dx + (double(x >> 1) / coord_scale) * scale;
*y_ = dy + (double(y >> 1) / coord_scale) * scale;
switch(((y & 1) << 1) | (x & 1))
{
case cmd_move_to: return path_cmd_move_to;
@@ -67,6 +66,7 @@ namespace agg
template<class T, unsigned CoordShift=6> class path_storage_integer
{
public:
typedef T value_type;
typedef vertex_integer<T, CoordShift> vertex_integer_type;
//--------------------------------------------------------------------
@@ -110,12 +110,9 @@ namespace agg
//--------------------------------------------------------------------
unsigned size() const { return m_storage.size(); }
unsigned vertex(unsigned idx, T* x, T* y) const
unsigned vertex(unsigned idx, double* x, double* y) const
{
const vertex_integer_type& v = m_storage[idx];
*x = v.x >> 1;
*y = v.y >> 1;
return ((v.y & 1) << 1) | (v.x & 1);
return m_storage[idx].vertex(x, y);
}
//--------------------------------------------------------------------
@@ -130,7 +127,6 @@ namespace agg
}
}
//--------------------------------------------------------------------
void rewind(unsigned)
{
@@ -191,11 +187,10 @@ namespace agg
return bounds;
}
private:
pod_deque<vertex_integer_type, 6> m_storage;
unsigned m_vertex_idx;
bool m_closed;
pod_bvector<vertex_integer_type, 6> m_storage;
unsigned m_vertex_idx;
bool m_closed;
};
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -17,7 +17,7 @@
#include "agg_basics.h"
#include "agg_line_aa_basics.h"
#include "agg_color_rgba8.h"
#include "agg_color_rgba.h"
namespace agg
@@ -29,43 +29,47 @@ namespace agg
typedef ColorT color_type;
static unsigned dilation() { return 0; }
static void pixel_low_res(color_type const* const* buf,
color_type* p, int x, int y)
static void AGG_INLINE pixel_low_res(color_type const* const* buf,
color_type* p, int x, int y)
{
*p = buf[y][x];
}
static void pixel_high_res(color_type const* const* buf,
color_type* p, int x, int y)
static void AGG_INLINE pixel_high_res(color_type const* const* buf,
color_type* p, int x, int y)
{
*p = buf[y >> line_subpixel_shift]
[x >> line_subpixel_shift];
}
};
typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8;
typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8;
typedef pattern_filter_nn<rgba16> pattern_filter_nn_rgba16;
//===========================================pattern_filter_bilinear_rgba8
struct pattern_filter_bilinear_rgba8
//===========================================pattern_filter_bilinear_rgba
template<class ColorT> struct pattern_filter_bilinear_rgba
{
typedef rgba8 color_type;
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
static unsigned dilation() { return 1; }
static void pixel_low_res(color_type const* const* buf,
color_type* p, int x, int y)
static AGG_INLINE void pixel_low_res(color_type const* const* buf,
color_type* p, int x, int y)
{
*p = buf[y][x];
}
static void pixel_high_res(color_type const* const* buf,
color_type* p, int x, int y)
static AGG_INLINE void pixel_high_res(color_type const* const* buf,
color_type* p, int x, int y)
{
int r, g, b, a;
r = g = b = a = line_subpixel_size * line_subpixel_size / 2;
calc_type r, g, b, a;
r = g = b = a = line_subpixel_scale * line_subpixel_scale / 2;
int weight;
calc_type weight;
int x_lr = x >> line_subpixel_shift;
int y_lr = y >> line_subpixel_shift;
@@ -73,8 +77,8 @@ namespace agg
y &= line_subpixel_mask;
const color_type* ptr = buf[y_lr] + x_lr;
weight = (line_subpixel_size - x) *
(line_subpixel_size - y);
weight = (line_subpixel_scale - x) *
(line_subpixel_scale - y);
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
@@ -82,7 +86,7 @@ namespace agg
++ptr;
weight = x * (line_subpixel_size - y);
weight = x * (line_subpixel_scale - y);
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
@@ -90,7 +94,7 @@ namespace agg
ptr = buf[y_lr + 1] + x_lr;
weight = (line_subpixel_size - x) * y;
weight = (line_subpixel_scale - x) * y;
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
@@ -104,14 +108,15 @@ namespace agg
b += weight * ptr->b;
a += weight * ptr->a;
p->r = (int8u)(r >> line_subpixel_shift * 2);
p->g = (int8u)(g >> line_subpixel_shift * 2);
p->b = (int8u)(b >> line_subpixel_shift * 2);
p->a = (int8u)(a >> line_subpixel_shift * 2);
p->r = (value_type)(r >> line_subpixel_shift * 2);
p->g = (value_type)(g >> line_subpixel_shift * 2);
p->b = (value_type)(b >> line_subpixel_shift * 2);
p->a = (value_type)(a >> line_subpixel_shift * 2);
}
};
typedef pattern_filter_bilinear_rgba<rgba8> pattern_filter_bilinear_rgba8;
typedef pattern_filter_bilinear_rgba<rgba16> pattern_filter_bilinear_rgba16;
}
#endif
+54 -36
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -18,6 +18,7 @@
#include <string.h>
#include "agg_array.h"
#include "agg_rendering_buffer.h"
@@ -29,46 +30,49 @@ namespace agg
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::row_data row_data;
typedef AlphaMask amask_type;
typedef typename amask_type::cover_type cover_type;
private:
enum { span_extra_tail = 256 };
enum span_extra_tail_e { span_extra_tail = 256 };
void realloc_span(unsigned len)
{
if(len > m_max_len)
if(len > m_span.size())
{
delete [] m_span;
m_span = new cover_type[m_max_len = len + span_extra_tail];
m_span.resize(len + span_extra_tail);
}
}
void init_span(unsigned len)
{
realloc_span(len);
// ATTN! May work incorrectly if cover_type is more that one byte
memset(m_span, amask_type::cover_full, len * sizeof(cover_type));
memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type));
}
void init_span(unsigned len, const cover_type* covers)
{
realloc_span(len);
memcpy(m_span, covers, len * sizeof(cover_type));
memcpy(&m_span[0], covers, len * sizeof(cover_type));
}
public:
~pixfmt_amask_adaptor() { delete [] m_span; }
pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& mask) :
m_pixf(&pixf), m_mask(&mask), m_span(0), m_max_len(0)
m_pixf(&pixf), m_mask(&mask), m_span()
{}
void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; }
void attach_alpha_mask(const amask_type& mask) { m_mask = &mask; }
//--------------------------------------------------------------------
template<class PixFmt_>
bool attach_pixfmt(PixFmt_& pixf, int x1, int y1, int x2, int y2)
{
return m_pixf->attach(pixf, x1, y1, x2, y2);
}
//--------------------------------------------------------------------
unsigned width() const { return m_pixf->width(); }
unsigned height() const { return m_pixf->height(); }
@@ -97,8 +101,8 @@ namespace agg
const color_type& c)
{
realloc_span(len);
m_mask->fill_hspan(x, y, m_span, len);
m_pixf->blend_solid_hspan(x, y, len, c, m_span);
m_mask->fill_hspan(x, y, &m_span[0], len);
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
@@ -108,8 +112,8 @@ namespace agg
cover_type cover)
{
init_span(len);
m_mask->combine_hspan(x, y, m_span, len);
m_pixf->blend_solid_hspan(x, y, len, c, m_span);
m_mask->combine_hspan(x, y, &m_span[0], len);
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
@@ -118,8 +122,8 @@ namespace agg
const color_type& c)
{
realloc_span(len);
m_mask->fill_vspan(x, y, m_span, len);
m_pixf->blend_solid_vspan(x, y, len, c, m_span);
m_mask->fill_vspan(x, y, &m_span[0], len);
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
@@ -129,8 +133,8 @@ namespace agg
cover_type cover)
{
init_span(len);
m_mask->combine_vspan(x, y, m_span, len);
m_pixf->blend_solid_vspan(x, y, len, c, m_span);
m_mask->combine_vspan(x, y, &m_span[0], len);
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
@@ -150,8 +154,8 @@ namespace agg
const cover_type* covers)
{
init_span(len, covers);
m_mask->combine_hspan(x, y, m_span, len);
m_pixf->blend_solid_hspan(x, y, len, c, m_span);
m_mask->combine_hspan(x, y, &m_span[0], len);
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
}
@@ -162,11 +166,27 @@ namespace agg
const cover_type* covers)
{
init_span(len, covers);
m_mask->combine_vspan(x, y, m_span, len);
m_pixf->blend_solid_vspan(x, y, len, c, m_span);
m_mask->combine_vspan(x, y, &m_span[0], len);
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y, unsigned len, const color_type* colors)
{
realloc_span(len);
m_mask->fill_hspan(x, y, &m_span[0], len);
m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover_full);
}
//--------------------------------------------------------------------
void copy_color_vspan(int x, int y, unsigned len, const color_type* colors)
{
realloc_span(len);
m_mask->fill_vspan(x, y, &m_span[0], len);
m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover_full);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
@@ -177,14 +197,14 @@ namespace agg
if(covers)
{
init_span(len, covers);
m_mask->combine_hspan(x, y, m_span, len);
m_mask->combine_hspan(x, y, &m_span[0], len);
}
else
{
realloc_span(len);
m_mask->fill_hspan(x, y, m_span, len);
m_mask->fill_hspan(x, y, &m_span[0], len);
}
m_pixf->blend_color_hspan(x, y, len, colors, m_span, cover);
m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover);
}
@@ -198,22 +218,20 @@ namespace agg
if(covers)
{
init_span(len, covers);
m_mask->combine_vspan(x, y, m_span, len);
m_mask->combine_vspan(x, y, &m_span[0], len);
}
else
{
realloc_span(len);
m_mask->fill_vspan(x, y, m_span, len);
m_mask->fill_vspan(x, y, &m_span[0], len);
}
m_pixf->blend_color_vspan(x, y, len, colors, m_span, cover);
m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover);
}
private:
pixfmt_type* m_pixf;
const amask_type* m_mask;
cover_type* m_span;
unsigned m_max_len;
pixfmt_type* m_pixf;
const amask_type* m_mask;
pod_array<cover_type> m_span;
};
}
-429
View File
@@ -1,429 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_CRB_RGBA32_INCLUDED
#define AGG_PIXFMT_CRB_RGBA32_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
namespace agg
{
//================================================pixel_formats_crb_rgba32
template<class RenBuf, class Order> class pixel_formats_crb_rgba32
{
public:
typedef rgba8 color_type;
typedef RenBuf buffer_type;
typedef Order order_type;
typedef typename RenBuf::row_data row_data;
//--------------------------------------------------------------------
pixel_formats_crb_rgba32(RenBuf& rb) : m_rbuf(&rb) {}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
const int8u* p = m_rbuf->span_ptr(x, y, 1);
return p ? color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]) :
color_type::no_color();
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return m_rbuf->span(x, y);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
int32u* p32 = (int32u*)(m_rbuf->span_ptr(x, y, len));
do
{
*p32++ = v;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
do
{
*(int32u*)(m_rbuf->span_ptr(x, y, 1)) = v;
++y;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
int32u* p32 = (int32u*)(m_rbuf->span_ptr(x, y, len));
do
{
*p32++ = v;
}
while(--len);
}
else
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
p += 4;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
do
{
*(int32u*)(m_rbuf->span_ptr(x, y, 1)) = v;
++y;
}
while(--len);
}
else
{
do
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
++y;
}
while(--len);
}
}
//--------------------------------------------------------------------
template<class RenBuf2> void copy_from(const RenBuf2& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
const int8u* p = from.row(ysrc);
if(p)
{
p += xsrc << 2;
memmove(m_rbuf->span_ptr(xdst, ydst, len), p, len * 4);
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const int8u* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
int8u* pdst = m_rbuf->span_ptr(xdst, ydst, len);
int incp = 4;
if(xdst > xsrc)
{
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do
{
int alpha = psrc[src_order::A];
if(alpha)
{
if(alpha == 255)
{
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
}
else
{
int r = pdst[Order::R];
int g = pdst[Order::G];
int b = pdst[Order::B];
int a = pdst[Order::A];
pdst[Order::R] = (int8u)((((psrc[src_order::R] - r) * alpha) + (r << 8)) >> 8);
pdst[Order::G] = (int8u)((((psrc[src_order::G] - g) * alpha) + (g << 8)) >> 8);
pdst[Order::B] = (int8u)((((psrc[src_order::B] - b) * alpha) + (b << 8)) >> 8);
pdst[Order::A] = (int8u)((alpha + a) - ((alpha * a) >> 8));
}
}
psrc += incp;
pdst += incp;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
do
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
++y;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)colors->r;
p[Order::G] = (int8u)colors->g;
p[Order::B] = (int8u)colors->b;
p[Order::A] = (int8u)colors->a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += 4;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
do
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)colors->r;
p[Order::G] = (int8u)colors->g;
p[Order::B] = (int8u)colors->b;
p[Order::A] = (int8u)colors->a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
++y;
++colors;
}
while(--len);
}
private:
RenBuf* m_rbuf;
};
}
#endif
@@ -1,345 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_CRB_RGBA32_PRE_INCLUDED
#define AGG_PIXFMT_CRB_RGBA32_PRE_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
namespace agg
{
//============================================pixel_formats_crb_rgba32_pre
template<class RenBuf, class Order> class pixel_formats_crb_rgba32_pre
{
public:
typedef rgba8 color_type;
typedef RenBuf buffer_type;
typedef Order order_type;
typedef typename RenBuf::row_data row_data;
private:
//--------------------------------------------------------------------
static inline void copy_pix(int8u* p, const color_type& c)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
static inline void blend_pix(int8u* p, const color_type& c,
unsigned cover, unsigned alpha)
{
p[Order::R] = (int8u)((p[Order::R] * alpha + ((c.r * cover) << 8)) >> 16);
p[Order::G] = (int8u)((p[Order::G] * alpha + ((c.g * cover) << 8)) >> 16);
p[Order::B] = (int8u)((p[Order::B] * alpha + ((c.b * cover) << 8)) >> 16);
p[Order::A] = (int8u)(255 - ((alpha * (255 - p[Order::A])) >> 16));
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c, unsigned cover)
{
unsigned alpha = 65535 - cover * c.a;
if(alpha < 65535)
{
if(alpha <= 65535-255*255)
{
copy_pix(p, c);
}
else
{
blend_pix(p, c, cover, alpha);
}
}
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c)
{
unsigned alpha = 255 - c.a;
if(alpha < 255)
{
if(alpha == 0)
{
copy_pix(p, c);
}
else
{
p[Order::R] = (int8u)((p[Order::R] * alpha + (c.r << 8)) >> 8);
p[Order::G] = (int8u)((p[Order::G] * alpha + (c.g << 8)) >> 8);
p[Order::B] = (int8u)((p[Order::B] * alpha + (c.b << 8)) >> 8);
p[Order::A] = (int8u)(255 - ((alpha * (255 - p[Order::A])) >> 8));
}
}
}
public:
//--------------------------------------------------------------------
pixel_formats_crb_rgba32_pre(RenBuf& rb) : m_rbuf(&rb) {}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
const int8u* p = m_rbuf->span_ptr(x, y, 1);
return p ? color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]) :
color_type::no_color();
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return m_rbuf->span(x, y);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix(m_rbuf->span_ptr(x, y, 1), c, cover);
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
copy_pix((int8u*)&v, c);
int32u* p32 = (int32u*)(m_rbuf->span_ptr(x, y, len));
do
{
*p32++ = v;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
copy_pix((int8u*)&v, c);
do
{
*(int32u*)(m_rbuf->span_ptr(x, y, 1)) = v;
++y;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
int32u v;
copy_pix((int8u*)&v, c);
int32u* p32 = (int32u*)(m_rbuf->span_ptr(x, y, len));
do
{
*p32++ = v;
}
while(--len);
}
else
{
int8u* p = m_rbuf->span_ptr(x, y, len);
alpha = 65535 - alpha;
do
{
blend_pix(p, c, cover, alpha);
p += 4;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
int32u v;
copy_pix((int8u*)&v, c);
do
{
*(int32u*)(m_rbuf->span_ptr(x, y, 1)) = v;
++y;
}
while(--len);
}
else
{
alpha = 65535 - alpha;
do
{
blend_pix(m_rbuf->span_ptr(x, y, 1), c, cover, alpha);
++y;
}
while(--len);
}
}
//--------------------------------------------------------------------
template<class RenBuf2> void copy_from(const RenBuf2& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
const int8u* p = from.row(ysrc);
if(p)
{
p += xsrc << 2;
memmove(m_rbuf->span_ptr(xdst, ydst, len), p, len * 4);
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const int8u* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
int8u* pdst = m_rbuf->span_ptr(xdst, ydst, len);
int incp = 4;
if(xdst > xsrc)
{
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do
{
unsigned alpha = 255 - psrc[src_order::A];
if(alpha < 255)
{
if(alpha == 0)
{
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
}
else
{
pdst[Order::R] = (int8u)((pdst[Order::R] * alpha + (psrc[src_order::R] << 8)) >> 8);
pdst[Order::G] = (int8u)((pdst[Order::G] * alpha + (psrc[src_order::G] << 8)) >> 8);
pdst[Order::B] = (int8u)((pdst[Order::B] * alpha + (psrc[src_order::B] << 8)) >> 8);
pdst[Order::A] = (int8u)(255 - ((alpha * (255 - pdst[Order::A])) >> 8));
}
}
psrc += incp;
pdst += incp;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
copy_or_blend_pix(p, c, *covers++);
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
do
{
copy_or_blend_pix(m_rbuf->span_ptr(x, y, 1), c, *covers++);
++y;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
do
{
copy_or_blend_pix(m_rbuf->span_ptr(x, y, 1),
*colors++,
covers ? *covers++ : cover);
++y;
}
while(--len);
}
private:
RenBuf* m_rbuf;
};
}
#endif
+618
View File
@@ -0,0 +1,618 @@
//----------------------------------------------------------------------------
// 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for high precision colors has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_GRAY_INCLUDED
#define AGG_PIXFMT_GRAY_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_gray.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//============================================================blender_gray
template<class ColorT> struct blender_gray
{
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e { base_shift = color_type::base_shift };
static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
unsigned alpha, unsigned cover=0)
{
*p = (value_type)((((cv - calc_type(*p)) * alpha) + (calc_type(*p) << base_shift)) >> base_shift);
}
};
//======================================================blender_gray_pre
template<class ColorT> struct blender_gray_pre
{
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e { base_shift = color_type::base_shift };
static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
unsigned alpha, unsigned cover)
{
alpha = color_type::base_mask - alpha;
cover = (cover + 1) << (base_shift - 8);
*p = (value_type)((*p * alpha + cv * cover) >> base_shift);
}
static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
unsigned alpha)
{
*p = (value_type)(((*p * (color_type::base_mask - alpha)) >> base_shift) + cv);
}
};
//=====================================================apply_gamma_dir_gray
template<class ColorT, class GammaLut> class apply_gamma_dir_gray
{
public:
typedef typename ColorT::value_type value_type;
apply_gamma_dir_gray(const GammaLut& gamma) : m_gamma(gamma) {}
AGG_INLINE void operator () (value_type* p)
{
*p = m_gamma.dir(*p);
}
private:
const GammaLut& m_gamma;
};
//=====================================================apply_gamma_inv_gray
template<class ColorT, class GammaLut> class apply_gamma_inv_gray
{
public:
typedef typename ColorT::value_type value_type;
apply_gamma_inv_gray(const GammaLut& gamma) : m_gamma(gamma) {}
AGG_INLINE void operator () (value_type* p)
{
*p = m_gamma.inv(*p);
}
private:
const GammaLut& m_gamma;
};
//=================================================pixfmt_alpha_blend_gray
template<class Blender, class RenBuf, unsigned Step=1, unsigned Offset=0>
class pixfmt_alpha_blend_gray
{
public:
typedef RenBuf rbuf_type;
typedef typename rbuf_type::row_data row_data;
typedef Blender blender_type;
typedef typename blender_type::color_type color_type;
typedef int order_type; // A fake one
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e
{
base_shift = color_type::base_shift,
base_scale = color_type::base_scale,
base_mask = color_type::base_mask,
pix_width = sizeof(value_type),
pix_step = Step,
pix_offset = Offset
};
private:
//--------------------------------------------------------------------
static AGG_INLINE void copy_or_blend_pix(value_type* p,
const color_type& c,
unsigned cover)
{
if (c.a)
{
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
*p = c.v;
}
else
{
Blender::blend_pix(p, c.v, alpha, cover);
}
}
}
static AGG_INLINE void copy_or_blend_pix(value_type* p,
const color_type& c)
{
if (c.a)
{
if(c.a == base_mask)
{
*p = c.v;
}
else
{
Blender::blend_pix(p, c.v, c.a);
}
}
}
public:
//--------------------------------------------------------------------
pixfmt_alpha_blend_gray(rbuf_type& rb) :
m_rbuf(&rb)
{}
void attach(rbuf_type& rb) { m_rbuf = &rb; }
//--------------------------------------------------------------------
template<class PixFmt>
bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
{
rect_i r(x1, y1, x2, y2);
if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
{
int stride = pixf.stride();
m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
(r.x2 - r.x1) + 1,
(r.y2 - r.y1) + 1,
stride);
return true;
}
return false;
}
//--------------------------------------------------------------------
AGG_INLINE unsigned width() const { return m_rbuf->width(); }
AGG_INLINE unsigned height() const { return m_rbuf->height(); }
AGG_INLINE int stride() const { return m_rbuf->stride(); }
//--------------------------------------------------------------------
int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
row_data row(int y) const { return m_rbuf->row(y); }
const int8u* pix_ptr(int x, int y) const
{
return m_rbuf->row_ptr(y) + x * Step + Offset;
}
int8u* pix_ptr(int x, int y)
{
return m_rbuf->row_ptr(y) + x * Step + Offset;
}
//--------------------------------------------------------------------
AGG_INLINE static void make_pix(int8u* p, const color_type& c)
{
*(value_type*)p = c.v;
}
//--------------------------------------------------------------------
AGG_INLINE color_type pixel(int x, int y) const
{
value_type* p = (value_type*)m_rbuf->row_ptr(y) + x * Step + Offset;
return color_type(*p);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
*((value_type*)m_rbuf->row_ptr(x, y, 1) + x * Step + Offset) = c.v;
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix((value_type*)
m_rbuf->row_ptr(x, y, 1) + x * Step + Offset,
c,
cover);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
do
{
*p = c.v;
p += Step;
}
while(--len);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
do
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
*p = c.v;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
if (c.a)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
do
{
*p = c.v;
p += Step;
}
while(--len);
}
else
{
do
{
Blender::blend_pix(p, c.v, alpha, cover);
p += Step;
}
while(--len);
}
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
if (c.a)
{
value_type* p;
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
*p = c.v;
}
while(--len);
}
else
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
Blender::blend_pix(p, c.v, alpha, cover);
}
while(--len);
}
}
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
if (c.a)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
do
{
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
if(alpha == base_mask)
{
*p = c.v;
}
else
{
Blender::blend_pix(p, c.v, alpha, *covers);
}
p += Step;
++covers;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
if (c.a)
{
do
{
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
if(alpha == base_mask)
{
*p = c.v;
}
else
{
Blender::blend_pix(p, c.v, alpha, *covers);
}
++covers;
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y,
unsigned len,
const color_type* colors)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
do
{
*p = colors->v;
p += Step;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_color_vspan(int x, int y,
unsigned len,
const color_type* colors)
{
do
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
*p = colors->v;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
if(covers)
{
do
{
copy_or_blend_pix(p, *colors++, *covers++);
p += Step;
}
while(--len);
}
else
{
if(cover == 255)
{
do
{
if(colors->a == base_mask)
{
*p = colors->v;
}
else
{
copy_or_blend_pix(p, *colors);
}
p += Step;
++colors;
}
while(--len);
}
else
{
do
{
copy_or_blend_pix(p, *colors++, cover);
p += Step;
}
while(--len);
}
}
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
value_type* p;
if(covers)
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
copy_or_blend_pix(p, *colors++, *covers++);
}
while(--len);
}
else
{
if(cover == 255)
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
if(colors->a == base_mask)
{
*p = colors->v;
}
else
{
copy_or_blend_pix(p, *colors);
}
++colors;
}
while(--len);
}
else
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
copy_or_blend_pix(p, *colors++, cover);
}
while(--len);
}
}
}
//--------------------------------------------------------------------
template<class Function> void for_each_pixel(Function f)
{
unsigned y;
for(y = 0; y < height(); ++y)
{
row_data r = m_rbuf->row(y);
if(r.ptr)
{
unsigned len = r.x2 - r.x1 + 1;
value_type* p = (value_type*)
m_rbuf->row_ptr(r.x1, y, len) + r.x1 * Step + Offset;
do
{
f(p);
p += Step;
}
while(--len);
}
}
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
{
for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
{
for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class RenBuf2>
void copy_from(const RenBuf2& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
const int8u* p = from.row_ptr(ysrc);
if(p)
{
memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
p + xsrc * pix_width,
len * pix_width);
}
}
private:
rbuf_type* m_rbuf;
};
typedef blender_gray<gray8> blender_gray8;
typedef blender_gray_pre<gray8> blender_gray8_pre;
typedef blender_gray<gray16> blender_gray16;
typedef blender_gray_pre<gray16> blender_gray16_pre;
typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8; //----pixfmt_gray8
typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre; //----pixfmt_gray8_pre
typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16; //----pixfmt_gray16
typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre; //----pixfmt_gray16_pre
}
#endif
-321
View File
@@ -1,321 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_GRAY8_INCLUDED
#define AGG_PIXFMT_GRAY8_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_gray8.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//======================================================pixfmt_gray8_base
template<unsigned Step=1, unsigned Offset=0>
class pixfmt_gray8_base
{
public:
typedef gray8 color_type;
typedef bool order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixfmt_gray8_base(rendering_buffer& rb)
: m_rbuf(&rb)
{
}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
return color_type(m_rbuf->row(y)[x * Step + Offset]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
m_rbuf->row(y)[x * Step + Offset] = (int8u)c.v;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + x * Step + Offset;
int v = *p;
int alpha = int(cover) * c.a;
*p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16);
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int8u* p = m_rbuf->row(y) + x * Step + Offset;
do
{
*p = (int8u)c.v;
p += Step;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int8u* p = m_rbuf->row(y) + x * Step + Offset;
do
{
*p = (int8u)c.v;
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + x * Step + Offset;
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
do
{
*p = (int8u)c.v;
p += Step;
}
while(--len);
}
else
{
do
{
int v = *p;
*p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16);
p += Step;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + x * Step + Offset;
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
do
{
*p = (int8u)c.v;
p += m_rbuf->stride();
}
while(--len);
}
else
{
do
{
int v = *p;
*p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16);
p += m_rbuf->stride();
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
memmove(m_rbuf->row(ydst) + xdst * Step + Offset,
(const void*)(from.row(ysrc) + xsrc * Step + Offset),
len * Step);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + x * Step + Offset;
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
*p = (int8u)c.v;
}
else
{
int v = *p;
*p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16);
}
}
p += Step;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + x * Step + Offset;
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
*p = (int8u)c.v;
}
else
{
int v = *p;
*p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16);
}
}
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x * Step + Offset;
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
*p = (int8u)colors->v;
}
else
{
int v = *p;
*p = (int8u)((((colors->v - v) * alpha) + (v << 16)) >> 16);
}
}
p += Step;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x * Step + Offset;
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
*p = (int8u)colors->v;
}
else
{
int v = *p;
*p = (int8u)((((colors->v - v) * alpha) + (v << 16)) >> 16);
}
}
p += m_rbuf->stride();
++colors;
}
while(--len);
}
private:
rendering_buffer* m_rbuf;
};
typedef pixfmt_gray8_base<1, 0> pixfmt_gray8; //----pixfmt_gray8
typedef pixfmt_gray8_base<3, 0> pixfmt_gray8_rgb24r; //----pixfmt_gray8_rgb24r
typedef pixfmt_gray8_base<3, 1> pixfmt_gray8_rgb24g; //----pixfmt_gray8_rgb24g
typedef pixfmt_gray8_base<3, 2> pixfmt_gray8_rgb24b; //----pixfmt_gray8_rgb24b
typedef pixfmt_gray8_base<3, 2> pixfmt_gray8_bgr24r; //----pixfmt_gray8_bgr24r
typedef pixfmt_gray8_base<3, 1> pixfmt_gray8_bgr24g; //----pixfmt_gray8_bgr24g
typedef pixfmt_gray8_base<3, 0> pixfmt_gray8_bgr24b; //----pixfmt_gray8_bgr24b
typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_rgba32r; //----pixfmt_gray8_rgba32r
typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_rgba32g; //----pixfmt_gray8_rgba32g
typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_rgba32b; //----pixfmt_gray8_rgba32b
typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_rgba32a; //----pixfmt_gray8_rgba32a
typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_argb32r; //----pixfmt_gray8_argb32r
typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_argb32g; //----pixfmt_gray8_argb32g
typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_argb32b; //----pixfmt_gray8_argb32b
typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_argb32a; //----pixfmt_gray8_argb32a
typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_bgra32r; //----pixfmt_gray8_bgra32r
typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_bgra32g; //----pixfmt_gray8_bgra32g
typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_bgra32b; //----pixfmt_gray8_bgra32b
typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_bgra32a; //----pixfmt_gray8_bgra32a
typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_abgr32r; //----pixfmt_gray8_abgr32r
typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_abgr32g; //----pixfmt_gray8_abgr32g
typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_abgr32b; //----pixfmt_gray8_abgr32b
typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_abgr32a; //----pixfmt_gray8_abgr32a
}
#endif
+792
View File
@@ -0,0 +1,792 @@
//----------------------------------------------------------------------------
// 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for high precision colors has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGB_INCLUDED
#define AGG_PIXFMT_RGB_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//=====================================================apply_gamma_dir_rgb
template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb
{
public:
typedef typename ColorT::value_type value_type;
apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
AGG_INLINE void operator () (value_type* p)
{
p[Order::R] = m_gamma.dir(p[Order::R]);
p[Order::G] = m_gamma.dir(p[Order::G]);
p[Order::B] = m_gamma.dir(p[Order::B]);
}
private:
const GammaLut& m_gamma;
};
//=====================================================apply_gamma_inv_rgb
template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb
{
public:
typedef typename ColorT::value_type value_type;
apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
AGG_INLINE void operator () (value_type* p)
{
p[Order::R] = m_gamma.inv(p[Order::R]);
p[Order::G] = m_gamma.inv(p[Order::G]);
p[Order::B] = m_gamma.inv(p[Order::B]);
}
private:
const GammaLut& m_gamma;
};
//=========================================================blender_rgb
template<class ColorT, class Order> struct blender_rgb
{
typedef ColorT color_type;
typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e { base_shift = color_type::base_shift };
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha,
unsigned cover=0)
{
p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >> base_shift);
p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha) >> base_shift);
p[Order::B] += (value_type)(((cb - p[Order::B]) * alpha) >> base_shift);
}
};
//======================================================blender_rgb_pre
template<class ColorT, class Order> struct blender_rgb_pre
{
typedef ColorT color_type;
typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e { base_shift = color_type::base_shift };
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha,
unsigned cover)
{
alpha = color_type::base_mask - alpha;
cover = (cover + 1) << (base_shift - 8);
p[Order::R] = (value_type)((p[Order::R] * alpha + cr * cover) >> base_shift);
p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift);
p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift);
}
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha)
{
alpha = color_type::base_mask - alpha;
p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr);
p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg);
p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb);
}
};
//===================================================blender_rgb_gamma
template<class ColorT, class Order, class Gamma> class blender_rgb_gamma
{
public:
typedef ColorT color_type;
typedef Order order_type;
typedef Gamma gamma_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e { base_shift = color_type::base_shift };
//--------------------------------------------------------------------
blender_rgb_gamma() : m_gamma(0) {}
void gamma(const gamma_type& g) { m_gamma = &g; }
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha,
unsigned cover=0)
{
calc_type r = m_gamma->dir(p[Order::R]);
calc_type g = m_gamma->dir(p[Order::G]);
calc_type b = m_gamma->dir(p[Order::B]);
p[Order::R] = m_gamma->inv((((m_gamma->dir(cr) - r) * alpha) >> base_shift) + r);
p[Order::G] = m_gamma->inv((((m_gamma->dir(cg) - g) * alpha) >> base_shift) + g);
p[Order::B] = m_gamma->inv((((m_gamma->dir(cb) - b) * alpha) >> base_shift) + b);
}
private:
const gamma_type* m_gamma;
};
//==================================================pixfmt_alpha_blend_rgb
template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb
{
public:
typedef RenBuf rbuf_type;
typedef Blender blender_type;
typedef typename rbuf_type::row_data row_data;
typedef typename blender_type::color_type color_type;
typedef typename blender_type::order_type order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e
{
base_shift = color_type::base_shift,
base_scale = color_type::base_scale,
base_mask = color_type::base_mask,
pix_width = sizeof(value_type) * 3
};
private:
//--------------------------------------------------------------------
AGG_INLINE void copy_or_blend_pix(value_type* p,
const color_type& c,
unsigned cover)
{
if (c.a)
{
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
}
else
{
m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
}
}
}
//--------------------------------------------------------------------
AGG_INLINE void copy_or_blend_pix(value_type* p,
const color_type& c)
{
if (c.a)
{
if(c.a == base_mask)
{
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
}
else
{
m_blender.blend_pix(p, c.r, c.g, c.b, c.a);
}
}
}
public:
//--------------------------------------------------------------------
pixfmt_alpha_blend_rgb(rbuf_type& rb) :
m_rbuf(&rb)
{}
void attach(rbuf_type& rb) { m_rbuf = &rb; }
//--------------------------------------------------------------------
template<class PixFmt>
bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
{
rect_i r(x1, y1, x2, y2);
if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
{
int stride = pixf.stride();
m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
(r.x2 - r.x1) + 1,
(r.y2 - r.y1) + 1,
stride);
return true;
}
return false;
}
//--------------------------------------------------------------------
Blender& blender() { return m_blender; }
//--------------------------------------------------------------------
AGG_INLINE unsigned width() const { return m_rbuf->width(); }
AGG_INLINE unsigned height() const { return m_rbuf->height(); }
AGG_INLINE int stride() const { return m_rbuf->stride(); }
//--------------------------------------------------------------------
AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
//--------------------------------------------------------------------
AGG_INLINE int8u* pix_ptr(int x, int y)
{
return m_rbuf->row_ptr(y) + x * pix_width;
}
AGG_INLINE const int8u* pix_ptr(int x, int y) const
{
return m_rbuf->row_ptr(y) + x * pix_width;
}
//--------------------------------------------------------------------
AGG_INLINE static void make_pix(int8u* p, const color_type& c)
{
((value_type*)p)[order_type::R] = c.r;
((value_type*)p)[order_type::G] = c.g;
((value_type*)p)[order_type::B] = c.b;
}
//--------------------------------------------------------------------
AGG_INLINE color_type pixel(int x, int y) const
{
value_type* p = (value_type*)m_rbuf->row_ptr(y) + x + x + x;
return color_type(p[order_type::R],
p[order_type::G],
p[order_type::B]);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x;
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix((value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x, c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + x + x + x;
do
{
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
do
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x + x + x;
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
if (c.a)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x + x + x;
calc_type alpha = (calc_type(c.a) * (calc_type(cover) + 1)) >> 8;
if(alpha == base_mask)
{
do
{
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
p += 3;
}
while(--len);
}
else
{
do
{
m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
p += 3;
}
while(--len);
}
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
if (c.a)
{
value_type* p;
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x + x + x;
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
}
while(--len);
}
else
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x + x + x;
m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
}
while(--len);
}
}
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
if (c.a)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x + x + x;
do
{
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
if(alpha == base_mask)
{
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
}
else
{
m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers);
}
p += 3;
++covers;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
if (c.a)
{
do
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x + x + x;
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
if(alpha == base_mask)
{
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
}
else
{
m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers);
}
++covers;
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y,
unsigned len,
const color_type* colors)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x + x + x;
do
{
p[order_type::R] = colors->r;
p[order_type::G] = colors->g;
p[order_type::B] = colors->b;
++colors;
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_color_vspan(int x, int y,
unsigned len,
const color_type* colors)
{
do
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x + x + x;
p[order_type::R] = colors->r;
p[order_type::G] = colors->g;
p[order_type::B] = colors->b;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x + x + x;
if(covers)
{
do
{
copy_or_blend_pix(p, *colors++, *covers++);
p += 3;
}
while(--len);
}
else
{
if(cover == 255)
{
do
{
copy_or_blend_pix(p, *colors++);
p += 3;
}
while(--len);
}
else
{
do
{
copy_or_blend_pix(p, *colors++, cover);
p += 3;
}
while(--len);
}
}
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
value_type* p;
if(covers)
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x + x + x;
copy_or_blend_pix(p, *colors++, *covers++);
}
while(--len);
}
else
{
if(cover == 255)
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x + x + x;
copy_or_blend_pix(p, *colors++);
}
while(--len);
}
else
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x + x + x;
copy_or_blend_pix(p, *colors++, cover);
}
while(--len);
}
}
}
//--------------------------------------------------------------------
template<class Function> void for_each_pixel(Function f)
{
unsigned y;
for(y = 0; y < height(); ++y)
{
row_data r = m_rbuf->row(y);
if(r.ptr)
{
unsigned len = r.x2 - r.x1 + 1;
value_type* p = (value_type*)
m_rbuf->row_ptr(r.x1, y, len) + r.x1 * 3;
do
{
f(p);
p += 3;
}
while(--len);
}
}
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
{
for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
{
for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class RenBuf2>
void copy_from(const RenBuf2& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
const int8u* p = from.row_ptr(ysrc);
if(p)
{
memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
p + xsrc * pix_width,
len * pix_width);
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len,
int8u cover)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
if(psrc)
{
psrc += xsrc * 4;
value_type* pdst =
(value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3;
if(cover == 255)
{
do
{
value_type alpha = psrc[src_order::A];
if(alpha)
{
if(alpha == base_mask)
{
pdst[order_type::R] = psrc[src_order::R];
pdst[order_type::G] = psrc[src_order::G];
pdst[order_type::B] = psrc[src_order::B];
}
else
{
m_blender.blend_pix(pdst,
psrc[src_order::R],
psrc[src_order::G],
psrc[src_order::B],
alpha);
}
}
psrc += 4;
pdst += 3;
}
while(--len);
}
else
{
color_type color;
do
{
color.r = psrc[src_order::R];
color.g = psrc[src_order::G];
color.b = psrc[src_order::B];
color.a = psrc[src_order::A];
copy_or_blend_pix(pdst, color, cover);
psrc += 4;
pdst += 3;
}
while(--len);
}
}
}
private:
rbuf_type* m_rbuf;
Blender m_blender;
};
typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8, order_rgb>, rendering_buffer> pixfmt_rgb24; //----pixfmt_rgb24
typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8, order_bgr>, rendering_buffer> pixfmt_bgr24; //----pixfmt_bgr24
typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48; //----pixfmt_rgb48
typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48; //----pixfmt_bgr48
typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8, order_rgb>, rendering_buffer> pixfmt_rgb24_pre; //----pixfmt_rgb24_pre
typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8, order_bgr>, rendering_buffer> pixfmt_bgr24_pre; //----pixfmt_bgr24_pre
typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48_pre; //----pixfmt_rgb48_pre
typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48_pre; //----pixfmt_bgr48_pre
//-----------------------------------------------------pixfmt_rgb24_gamma
template<class Gamma> class pixfmt_rgb24_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>
{
public:
pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>(rb)
{
this->blender().gamma(g);
}
};
//-----------------------------------------------------pixfmt_bgr24_gamma
template<class Gamma> class pixfmt_bgr24_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>
{
public:
pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>(rb)
{
this->blender().gamma(g);
}
};
//-----------------------------------------------------pixfmt_rgb48_gamma
template<class Gamma> class pixfmt_rgb48_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>
{
public:
pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>(rb)
{
this->blender().gamma(g);
}
};
//-----------------------------------------------------pixfmt_bgr48_gamma
template<class Gamma> class pixfmt_bgr48_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>
{
public:
pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>(rb)
{
this->blender().gamma(g);
}
};
}
#endif
-363
View File
@@ -1,363 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGB24_INCLUDED
#define AGG_PIXFMT_RGB24_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//=====================================================pixel_formats_rgb24
template<class Order> class pixel_formats_rgb24
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixel_formats_rgb24(rendering_buffer& rb)
: m_rbuf(&rb)
{
}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + x + x + x;
return color_type(p[Order::R], p[Order::G], p[Order::B]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 3);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->row(y) + x + x + x;
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
}
}
//--------------------------------------------------------------------
void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += 3;
}
while(--len);
}
else
{
do
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p += 3;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += m_rbuf->stride();
}
while(--len);
}
else
{
do
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p += m_rbuf->stride();
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
memmove(m_rbuf->row(ydst) + xdst * 3,
(const void*)(from.row(ysrc) + xsrc * 3), len * 3);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
}
else
{
int r = (int8u)p[Order::R];
int g = (int8u)p[Order::G];
int b = (int8u)p[Order::B];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
}
}
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
}
}
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
const int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)colors->r;
p[Order::G] = (int8u)colors->g;
p[Order::B] = (int8u)colors->b;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
}
}
p += 3;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
const int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)colors->r;
p[Order::G] = (int8u)colors->g;
p[Order::B] = (int8u)colors->b;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
}
}
p += m_rbuf->stride();
++colors;
}
while(--len);
}
private:
rendering_buffer* m_rbuf;
};
typedef pixel_formats_rgb24<order_rgb24> pixfmt_rgb24; //----pixfmt_rgb24
typedef pixel_formats_rgb24<order_bgr24> pixfmt_bgr24; //----pixfmt_bgr24
}
#endif
-339
View File
@@ -1,339 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGB24_GAMMA_INCLUDED
#define AGG_PIXFMT_RGB24_GAMMA_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
#include "agg_rendering_buffer.h"
#include "agg_gamma_lut.h"
namespace agg
{
//================================================pixel_formats_rgb24_gamma
template<class Order, class Gamma> class pixel_formats_rgb24_gamma
{
public:
typedef rgba8 color_type;
typedef Gamma gamma_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
private:
//--------------------------------------------------------------------
inline void blend_pix(int8u* p, const color_type& c, int alpha)
{
int r = m_gamma->dir(p[Order::R]);
int g = m_gamma->dir(p[Order::G]);
int b = m_gamma->dir(p[Order::B]);
p[Order::R] = m_gamma->inv((((m_gamma->dir(c.r) - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = m_gamma->inv((((m_gamma->dir(c.g) - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = m_gamma->inv((((m_gamma->dir(c.b) - b) * alpha) + (b << 16)) >> 16);
}
//--------------------------------------------------------------------
inline void copy_or_blend_pix(int8u* p, const color_type& c, int cover)
{
int alpha = int(c.a) * cover;
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
}
else
{
blend_pix(p, c, alpha);
}
}
}
//--------------------------------------------------------------------
inline void copy_or_blend_pix(int8u* p, const color_type& c)
{
if(c.a)
{
if(c.a == 255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
}
else
{
int r = m_gamma->dir(p[Order::R]);
int g = m_gamma->dir(p[Order::G]);
int b = m_gamma->dir(p[Order::B]);
p[Order::R] = m_gamma->inv((((m_gamma->dir(c.r) - r) * c.a) + (r << 8)) >> 8);
p[Order::G] = m_gamma->inv((((m_gamma->dir(c.g) - g) * c.a) + (g << 8)) >> 8);
p[Order::B] = m_gamma->inv((((m_gamma->dir(c.b) - b) * c.a) + (b << 8)) >> 8);
}
}
}
public:
//--------------------------------------------------------------------
pixel_formats_rgb24_gamma(rendering_buffer& rb, const gamma_type& g) :
m_rbuf(&rb),
m_gamma(&g)
{}
//--------------------------------------------------------------------
void gamma(const gamma_type& g) { m_gamma = &g; }
const gamma_type& gamma() const { return *m_gamma; }
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + x + x + x;
return color_type(p[Order::R], p[Order::G], p[Order::B]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 3);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->row(y) + x + x + x;
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix(m_rbuf->row(y) + x + x + x, c, cover);
}
//--------------------------------------------------------------------
void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += 3;
}
while(--len);
}
else
{
do
{
blend_pix(p, c, alpha);
p += 3;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += m_rbuf->stride();
}
while(--len);
}
else
{
do
{
blend_pix(p, c, alpha);
p += m_rbuf->stride();
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
memmove(m_rbuf->row(ydst) + xdst * 3,
(const void*)(from.row(ysrc) + xsrc * 3), len * 3);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
copy_or_blend_pix(p, c, *covers++);
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
copy_or_blend_pix(p, c, *covers++);
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += m_rbuf->stride();
}
while(--len);
}
private:
rendering_buffer* m_rbuf;
const gamma_type* m_gamma;
};
//-----------------------------------------------------pixfmt_rgb24_gamma
template<class Gamma> class pixfmt_rgb24_gamma :
public pixel_formats_rgb24_gamma<order_rgb24, Gamma>
{
public:
pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) :
pixel_formats_rgb24_gamma<order_rgb24, Gamma>(rb, g) {}
};
//-----------------------------------------------------pixfmt_bgr24_gamma
template<class Gamma> class pixfmt_bgr24_gamma :
public pixel_formats_rgb24_gamma<order_bgr24, Gamma>
{
public:
pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) :
pixel_formats_rgb24_gamma<order_bgr24, Gamma>(rb, g) {}
};
}
#endif
-299
View File
@@ -1,299 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGB24_PRE_INCLUDED
#define AGG_PIXFMT_RGB24_PRE_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//==================================================pixel_formats_rgb24_pre
template<class Order> class pixel_formats_rgb24_pre
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
private:
//--------------------------------------------------------------------
static inline void copy_pix(int8u* p, const color_type& c)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
}
//--------------------------------------------------------------------
static inline void blend_pix(int8u* p, const color_type& c,
unsigned cover, unsigned alpha)
{
p[Order::R] = (int8u)((p[Order::R] * alpha + ((c.r * cover) << 8)) >> 16);
p[Order::G] = (int8u)((p[Order::G] * alpha + ((c.g * cover) << 8)) >> 16);
p[Order::B] = (int8u)((p[Order::B] * alpha + ((c.b * cover) << 8)) >> 16);
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c, unsigned cover)
{
unsigned alpha = 65535 - cover * c.a;
if(alpha < 65535)
{
if(alpha <= 65535-255*255)
{
copy_pix(p, c);
}
else
{
blend_pix(p, c, cover, alpha);
}
}
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c)
{
unsigned alpha = 255 - c.a;
if(alpha < 255)
{
if(alpha == 0)
{
copy_pix(p, c);
}
else
{
p[Order::R] = (int8u)((p[Order::R] * alpha + (c.r << 8)) >> 8);
p[Order::G] = (int8u)((p[Order::G] * alpha + (c.g << 8)) >> 8);
p[Order::B] = (int8u)((p[Order::B] * alpha + (c.b << 8)) >> 8);
}
}
}
public:
//--------------------------------------------------------------------
pixel_formats_rgb24_pre(rendering_buffer& rb)
: m_rbuf(&rb)
{
}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + x + x + x;
return color_type(p[Order::R], p[Order::G], p[Order::B]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 3);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->row(y) + x + x + x;
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix(m_rbuf->row(y) + x + x + x, c, cover);
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
unsigned alpha = unsigned(cover) * c.a;
if(alpha == 255*255)
{
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += 3;
}
while(--len);
}
else
{
alpha = 65535 - alpha;
do
{
blend_pix(p, c, cover, alpha);
p += 3;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
unsigned alpha = unsigned(cover) * c.a;
if(alpha == 255*255)
{
do
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p += m_rbuf->stride();
}
while(--len);
}
else
{
alpha = 65535 - alpha;
do
{
blend_pix(p, c, cover, alpha);
p += m_rbuf->stride();
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
memmove(m_rbuf->row(ydst) + xdst * 3,
(const void*)(from.row(ysrc) + xsrc * 3), len * 3);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
copy_or_blend_pix(p, c, *covers++);
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
copy_or_blend_pix(p, c, *covers++);
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += 3;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + x + x + x;
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += m_rbuf->stride();
}
while(--len);
}
private:
rendering_buffer* m_rbuf;
};
typedef pixel_formats_rgb24_pre<order_rgb24> pixfmt_rgb24_pre; //----pixfmt_rgb24_pre
typedef pixel_formats_rgb24_pre<order_bgr24> pixfmt_bgr24_pre; //----pixfmt_bgr24_pre
}
#endif
-334
View File
@@ -1,334 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGB555_INCLUDED
#define AGG_PIXFMT_RGB555_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//------------------------------------------------------------------rgb555
inline int16u rgb555(unsigned r, unsigned g, unsigned b)
{
return (int16u)(((r & 0xF8) << 7) | ((g & 0xF8) << 2) | (b >> 3));
}
//===========================================================pixfmt_rgb555
class pixfmt_rgb555
{
public:
typedef rgba8 color_type;
typedef bool order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixfmt_rgb555(rendering_buffer& rb)
: m_rbuf(&rb)
{
}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
unsigned rgb = ((int16u*)(m_rbuf->row(y)))[x];
return color_type((rgb >> 7) & 0xF8,
(rgb >> 2) & 0xF8,
(rgb << 3) & 0xF8);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 2);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
((int16u*)(m_rbuf->row(y)))[x] = rgb555(c.r, c.g, c.b);
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
int alpha = int(cover) * c.a;
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
if(alpha == 255*255)
{
*p = rgb555(c.r, c.g, c.b);
}
else
{
int16u rgb = *p;
int r = (rgb >> 7) & 0xF8;
int g = (rgb >> 2) & 0xF8;
int b = (rgb << 3) & 0xF8;
*p = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
(((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
}
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
int16u v = rgb555(c.r, c.g, c.b);
do
{
*p++ = v;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int8u* p = m_rbuf->row(y) + (x << 1);
int16u v = rgb555(c.r, c.g, c.b);
do
{
*(int16u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
int16u v = rgb555(c.r, c.g, c.b);
do
{
*p++ = v;
}
while(--len);
}
else
{
do
{
int16u rgb = *p;
int r = (rgb >> 7) & 0xF8;
int g = (rgb >> 2) & 0xF8;
int b = (rgb << 3) & 0xF8;
*p++ = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
(((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 1);
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
int16u v = rgb555(c.r, c.g, c.b);
do
{
*(int16u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
else
{
do
{
int16u rgb = *(int16u*)p;
int r = (rgb >> 7) & 0xF8;
int g = (rgb >> 2) & 0xF8;
int b = (rgb << 3) & 0xF8;
*(int16u*)p = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
(((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
p += m_rbuf->stride();
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
memmove(m_rbuf->row(ydst) + xdst * 2,
(const void*)(from.row(ysrc) + xsrc * 2), len * 2);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
*p = rgb555(c.r, c.g, c.b);
}
else
{
int16u rgb = *p;
int r = (rgb >> 7) & 0xF8;
int g = (rgb >> 2) & 0xF8;
int b = (rgb << 3) & 0xF8;
*p = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
(((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
}
}
++p;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + (x << 1);
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
*(int16u*)p = rgb555(c.r, c.g, c.b);
}
else
{
int16u rgb = *(int16u*)p;
int r = (rgb >> 7) & 0xF8;
int g = (rgb >> 2) & 0xF8;
int b = (rgb << 3) & 0xF8;
*(int16u*)p = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
(((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
}
}
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
*(int16u*)p = rgb555(colors->r, colors->g, colors->b);
}
else
{
int16u rgb = *p;
int r = (rgb >> 7) & 0xF8;
int g = (rgb >> 2) & 0xF8;
int b = (rgb << 3) & 0xF8;
*(int16u*)p = (int16u)
((((((colors->r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
(((((colors->g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
((((colors->b - b) * alpha) + (b << 16)) >> 19));
}
}
++p;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 1);
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
*(int16u*)p = rgb555(colors->r, colors->g, colors->b);
}
else
{
int16u rgb = *(int16u*)p;
int r = (rgb >> 7) & 0xF8;
int g = (rgb >> 2) & 0xF8;
int b = (rgb << 3) & 0xF8;
*(int16u*)p = (int16u)
((((((colors->r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
(((((colors->g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
((((colors->b - b) * alpha) + (b << 16)) >> 19));
}
}
p += m_rbuf->stride();
++colors;
}
while(--len);
}
private:
rendering_buffer* m_rbuf;
};
}
#endif
-334
View File
@@ -1,334 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGB565_INCLUDED
#define AGG_PIXFMT_RGB565_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//------------------------------------------------------------------rgb565
inline int16u rgb565(unsigned r, unsigned g, unsigned b)
{
return (int16u)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
}
//===========================================================pixfmt_rgb565
class pixfmt_rgb565
{
public:
typedef rgba8 color_type;
typedef bool order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixfmt_rgb565(rendering_buffer& rb)
: m_rbuf(&rb)
{
}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
unsigned rgb = ((int16u*)(m_rbuf->row(y)))[x];
return color_type((rgb >> 8) & 0xF8,
(rgb >> 3) & 0xFC,
(rgb << 3) & 0xF8);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 2);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
((int16u*)(m_rbuf->row(y)))[x] = rgb565(c.r, c.g, c.b);
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
int alpha = int(cover) * c.a;
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
if(alpha == 255*255)
{
*p = rgb565(c.r, c.g, c.b);
}
else
{
int16u rgb = *p;
int r = (rgb >> 8) & 0xF8;
int g = (rgb >> 3) & 0xFC;
int b = (rgb << 3) & 0xF8;
*p = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
(((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
}
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
int16u v = rgb565(c.r, c.g, c.b);
do
{
*p++ = v;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int8u* p = m_rbuf->row(y) + (x << 1);
int16u v = rgb565(c.r, c.g, c.b);
do
{
*(int16u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
int16u v = rgb565(c.r, c.g, c.b);
do
{
*p++ = v;
}
while(--len);
}
else
{
do
{
int16u rgb = *p;
int r = (rgb >> 8) & 0xF8;
int g = (rgb >> 3) & 0xFC;
int b = (rgb << 3) & 0xF8;
*p++ = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
(((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 1);
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
int16u v = rgb565(c.r, c.g, c.b);
do
{
*(int16u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
else
{
do
{
int16u rgb = *(int16u*)p;
int r = (rgb >> 8) & 0xF8;
int g = (rgb >> 3) & 0xFC;
int b = (rgb << 3) & 0xF8;
*(int16u*)p = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
(((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
p += m_rbuf->stride();
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
memmove(m_rbuf->row(ydst) + xdst * 2,
(const void*)(from.row(ysrc) + xsrc * 2), len * 2);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
*p = rgb565(c.r, c.g, c.b);
}
else
{
int16u rgb = *p;
int r = (rgb >> 8) & 0xF8;
int g = (rgb >> 3) & 0xFC;
int b = (rgb << 3) & 0xF8;
*p = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
(((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
}
}
++p;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + (x << 1);
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
*(int16u*)p = rgb565(c.r, c.g, c.b);
}
else
{
int16u rgb = *(int16u*)p;
int r = (rgb >> 8) & 0xF8;
int g = (rgb >> 3) & 0xFC;
int b = (rgb << 3) & 0xF8;
*(int16u*)p = (int16u)
((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
(((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
((((c.b - b) * alpha) + (b << 16)) >> 19));
}
}
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int16u* p = (int16u*)(m_rbuf->row(y)) + x;
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
*(int16u*)p = rgb565(colors->r, colors->g, colors->b);
}
else
{
int16u rgb = *p;
int r = (rgb >> 8) & 0xF8;
int g = (rgb >> 3) & 0xFC;
int b = (rgb << 3) & 0xF8;
*p = (int16u)
((((((colors->r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
(((((colors->g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
((((colors->b - b) * alpha) + (b << 16)) >> 19));
}
}
++p;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 1);
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
*(int16u*)p = rgb565(colors->r, colors->g, colors->b);
}
else
{
int16u rgb = *(int16u*)p;
int r = (rgb >> 8) & 0xF8;
int g = (rgb >> 3) & 0xFC;
int b = (rgb << 3) & 0xF8;
*(int16u*)p = (int16u)
((((((colors->r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
(((((colors->g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
((((colors->b - b) * alpha) + (b << 16)) >> 19));
}
}
p += m_rbuf->stride();
++colors;
}
while(--len);
}
private:
rendering_buffer* m_rbuf;
};
}
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-432
View File
@@ -1,432 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGBA32_INCLUDED
#define AGG_PIXFMT_RGBA32_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//====================================================pixel_formats_rgba32
template<class Order> class pixel_formats_rgba32
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixel_formats_rgba32(rendering_buffer& rb)
: m_rbuf(&rb)
{
}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + (x << 2);
return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + (x << 2));
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->row(y) + (x << 2);
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
do
{
*p32++ = v;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
*(int32u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
do
{
*p32++ = v;
}
while(--len);
}
else
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
p += 4;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
do
{
*(int32u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
else
{
do
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
p += m_rbuf->stride();
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
memmove(m_rbuf->row(ydst) + xdst * 4,
(const void*)(from.row(ysrc) + xsrc * 4), len * 4);
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const int8u* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
int8u* pdst = m_rbuf->row(ydst) + (xdst << 2);
int incp = 4;
if(xdst > xsrc)
{
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do
{
int alpha = psrc[src_order::A];
if(alpha)
{
if(alpha == 255)
{
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
}
else
{
int r = pdst[Order::R];
int g = pdst[Order::G];
int b = pdst[Order::B];
int a = pdst[Order::A];
pdst[Order::R] = (int8u)((((psrc[src_order::R] - r) * alpha) + (r << 8)) >> 8);
pdst[Order::G] = (int8u)((((psrc[src_order::G] - g) * alpha) + (g << 8)) >> 8);
pdst[Order::B] = (int8u)((((psrc[src_order::B] - b) * alpha) + (b << 8)) >> 8);
pdst[Order::A] = (int8u)((alpha + a) - ((alpha * a) >> 8));
}
}
psrc += incp;
pdst += incp;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)colors->r;
p[Order::G] = (int8u)colors->g;
p[Order::B] = (int8u)colors->b;
p[Order::A] = (int8u)colors->a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += 4;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)colors->r;
p[Order::G] = (int8u)colors->g;
p[Order::B] = (int8u)colors->b;
p[Order::A] = (int8u)colors->a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += m_rbuf->stride();
++colors;
}
while(--len);
}
private:
rendering_buffer* m_rbuf;
};
typedef pixel_formats_rgba32<order_rgba32> pixfmt_rgba32; //----pixfmt_rgba32
typedef pixel_formats_rgba32<order_argb32> pixfmt_argb32; //----pixfmt_argb32
typedef pixel_formats_rgba32<order_abgr32> pixfmt_abgr32; //----pixfmt_abgr32
typedef pixel_formats_rgba32<order_bgra32> pixfmt_bgra32; //----pixfmt_bgra32
}
#endif
-322
View File
@@ -1,322 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGBA32_PLAIN_INCLUDED
#define AGG_PIXFMT_RGBA32_PLAIN_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//===============================================pixel_formats_rgba32_plain
template<class Order> class pixel_formats_rgba32_plain
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
private:
//--------------------------------------------------------------------
static inline void copy_pix(int8u* p, const color_type& c)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
static inline void blend_pix(int8u* p, const color_type& c, unsigned alpha)
{
int a = p[Order::A];
int r = p[Order::R] * a;
int g = p[Order::G] * a;
int b = p[Order::B] * a;
a = ((alpha << 8) + (a << 16)) - alpha * a;
p[Order::A] = (int8u)(a >> 16);
p[Order::R] = (int8u)((((((c.r << 8) - r) * alpha) + (r << 16)) / a));
p[Order::G] = (int8u)((((((c.g << 8) - g) * alpha) + (g << 16)) / a));
p[Order::B] = (int8u)((((((c.b << 8) - b) * alpha) + (b << 16)) / a));
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c, unsigned cover)
{
unsigned alpha = cover * c.a;
// For testing
//color_type c2 = c;
//c2.a = alpha >> 8;
//copy_or_blend_pix(p, c2);
if(alpha)
{
if(alpha == 255*255)
{
copy_pix(p, c);
}
else
{
blend_pix(p, c, alpha);
}
}
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c)
{
unsigned alpha = c.a;
if(alpha)
{
if(alpha == 255)
{
copy_pix(p, c);
}
else
{
int a = p[Order::A];
int r = p[Order::R] * a;
int g = p[Order::G] * a;
int b = p[Order::B] * a;
a = ((alpha + a) << 8) - alpha * a;
p[Order::A] = (int8u)(a >> 8);
p[Order::R] = (int8u)((((((c.r << 8) - r) * alpha) + (r << 8)) / a));
p[Order::G] = (int8u)((((((c.g << 8) - g) * alpha) + (g << 8)) / a));
p[Order::B] = (int8u)((((((c.b << 8) - b) * alpha) + (b << 8)) / a));
}
}
}
public:
//--------------------------------------------------------------------
pixel_formats_rgba32_plain(rendering_buffer& rb)
: m_rbuf(&rb)
{
}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + (x << 2);
return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + (x << 2));
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->row(y) + (x << 2);
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix(m_rbuf->row(y) + (x << 2), c, cover);
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
copy_pix((int8u*)&v, c);
int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
do
{
*p32++ = v;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
copy_pix((int8u*)&v, c);
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
*(int32u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
unsigned alpha = unsigned(cover) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
int32u v;
copy_pix((int8u*)&v, c);
int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
do
{
*p32++ = v;
}
while(--len);
}
else
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
blend_pix(p, c, alpha);
p += 4;
}
while(--len);
}
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
unsigned alpha = unsigned(cover) * c.a;
if(alpha)
{
unsigned alpha = unsigned(cover) * c.a;
if(alpha == 255*255)
{
int32u v;
copy_pix((int8u*)&v, c);
do
{
*(int32u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
else
{
do
{
blend_pix(p, c, alpha);
p += m_rbuf->stride();
}
while(--len);
}
}
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
memmove(m_rbuf->row(ydst) + xdst * 4,
(const void*)(from.row(ysrc) + xsrc * 4), len * 4);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
copy_or_blend_pix(p, c, *covers++);
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
copy_or_blend_pix(p, c, *covers++);
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += m_rbuf->stride();
}
while(--len);
}
private:
rendering_buffer* m_rbuf;
};
typedef pixel_formats_rgba32_plain<order_rgba32> pixfmt_rgba32_plain; //----pixfmt_rgba32_plain
typedef pixel_formats_rgba32_plain<order_argb32> pixfmt_argb32_plain; //----pixfmt_argb32_plain
typedef pixel_formats_rgba32_plain<order_abgr32> pixfmt_abgr32_plain; //----pixfmt_abgr32_plain
typedef pixel_formats_rgba32_plain<order_bgra32> pixfmt_bgra32_plain; //----pixfmt_bgra32_plain
}
#endif
-351
View File
@@ -1,351 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGBA32_PRE_INCLUDED
#define AGG_PIXFMT_RGBA32_PRE_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//=================================================pixel_formats_rgba32_pre
template<class Order> class pixel_formats_rgba32_pre
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
private:
//--------------------------------------------------------------------
static inline void copy_pix(int8u* p, const color_type& c)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
static inline void blend_pix(int8u* p, const color_type& c,
unsigned cover, unsigned alpha)
{
p[Order::R] = (int8u)((p[Order::R] * alpha + ((c.r * cover) << 8)) >> 16);
p[Order::G] = (int8u)((p[Order::G] * alpha + ((c.g * cover) << 8)) >> 16);
p[Order::B] = (int8u)((p[Order::B] * alpha + ((c.b * cover) << 8)) >> 16);
p[Order::A] = (int8u)(255 - ((alpha * (255 - p[Order::A])) >> 16));
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c, unsigned cover)
{
unsigned alpha = 65535 - cover * c.a;
if(alpha < 65535)
{
if(alpha <= 65535-255*255)
{
copy_pix(p, c);
}
else
{
blend_pix(p, c, cover, alpha);
}
}
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c)
{
unsigned alpha = 255 - c.a;
if(alpha < 255)
{
if(alpha == 0)
{
copy_pix(p, c);
}
else
{
p[Order::R] = (int8u)((p[Order::R] * alpha + (c.r << 8)) >> 8);
p[Order::G] = (int8u)((p[Order::G] * alpha + (c.g << 8)) >> 8);
p[Order::B] = (int8u)((p[Order::B] * alpha + (c.b << 8)) >> 8);
p[Order::A] = (int8u)(255 - ((alpha * (255 - p[Order::A])) >> 8));
}
}
}
public:
//--------------------------------------------------------------------
pixel_formats_rgba32_pre(rendering_buffer& rb)
: m_rbuf(&rb)
{
}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + (x << 2);
return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + (x << 2));
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->row(y) + (x << 2);
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix(m_rbuf->row(y) + (x << 2), c, cover);
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
copy_pix((int8u*)&v, c);
int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
do
{
*p32++ = v;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
copy_pix((int8u*)&v, c);
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
*(int32u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
unsigned alpha = unsigned(cover) * c.a;
if(alpha == 255*255)
{
int32u v;
copy_pix((int8u*)&v, c);
int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
do
{
*p32++ = v;
}
while(--len);
}
else
{
int8u* p = m_rbuf->row(y) + (x << 2);
alpha = 65535 - alpha;
do
{
blend_pix(p, c, cover, alpha);
p += 4;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
unsigned alpha = unsigned(cover) * c.a;
if(alpha == 255*255)
{
int32u v;
copy_pix((int8u*)&v, c);
do
{
*(int32u*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
else
{
alpha = 65535 - alpha;
do
{
blend_pix(p, c, cover, alpha);
p += m_rbuf->stride();
}
while(--len);
}
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
memmove(m_rbuf->row(ydst) + xdst * 4,
(const void*)(from.row(ysrc) + xsrc * 4), len * 4);
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const int8u* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
int8u* pdst = m_rbuf->row(ydst) + (xdst << 2);
int incp = 4;
if(xdst > xsrc)
{
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do
{
unsigned alpha = 255 - psrc[src_order::A];
if(alpha < 255)
{
if(alpha == 0)
{
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
}
else
{
pdst[Order::R] = (int8u)((pdst[Order::R] * alpha + (psrc[src_order::R] << 8)) >> 8);
pdst[Order::G] = (int8u)((pdst[Order::G] * alpha + (psrc[src_order::G] << 8)) >> 8);
pdst[Order::B] = (int8u)((pdst[Order::B] * alpha + (psrc[src_order::B] << 8)) >> 8);
pdst[Order::A] = (int8u)(255 - ((alpha * (255 - pdst[Order::A])) >> 8));
}
}
psrc += incp;
pdst += incp;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
copy_or_blend_pix(p, c, *covers++);
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
copy_or_blend_pix(p, c, *covers++);
p += m_rbuf->stride();
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->row(y) + (x << 2);
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += m_rbuf->stride();
}
while(--len);
}
private:
rendering_buffer* m_rbuf;
};
typedef pixel_formats_rgba32_pre<order_rgba32> pixfmt_rgba32_pre; //----pixfmt_rgba32_pre
typedef pixel_formats_rgba32_pre<order_argb32> pixfmt_argb32_pre; //----pixfmt_argb32_pre
typedef pixel_formats_rgba32_pre<order_abgr32> pixfmt_abgr32_pre; //----pixfmt_abgr32_pre
typedef pixel_formats_rgba32_pre<order_bgra32> pixfmt_bgra32_pre; //----pixfmt_bgra32_pre
}
#endif
+157
View File
@@ -0,0 +1,157 @@
//----------------------------------------------------------------------------
// 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_TRANSPOSER_INCLUDED
#define AGG_PIXFMT_TRANSPOSER_INCLUDED
#include "agg_basics.h"
namespace agg
{
//=======================================================pixfmt_transposer
template<class PixFmt> class pixfmt_transposer
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::row_data row_data;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
//--------------------------------------------------------------------
pixfmt_transposer() : m_pixf(0) {}
pixfmt_transposer(pixfmt_type& pixf) : m_pixf(&pixf) {}
void attach(pixfmt_type& pixf) { m_pixf = &pixf; }
//--------------------------------------------------------------------
AGG_INLINE unsigned width() const { return m_pixf->height(); }
AGG_INLINE unsigned height() const { return m_pixf->width(); }
//--------------------------------------------------------------------
AGG_INLINE color_type pixel(int x, int y) const
{
return m_pixf->pixel(y, x);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
m_pixf->copy_pixel(y, x, c);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y,
const color_type& c,
int8u cover)
{
m_pixf->blend_pixel(y, x, c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
m_pixf->copy_vline(y, x, len, c);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
m_pixf->copy_hline(y, x, len, c);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_hline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
m_pixf->blend_vline(y, x, len, c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_vline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
m_pixf->blend_hline(y, x, len, c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
m_pixf->blend_solid_vspan(y, x, len, c, covers);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
m_pixf->blend_solid_hspan(y, x, len, c, covers);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_color_hspan(int x, int y,
unsigned len,
const color_type* colors)
{
m_pixf->copy_color_vspan(y, x, len, colors);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_color_vspan(int x, int y,
unsigned len,
const color_type* colors)
{
m_pixf->copy_color_hspan(y, x, len, colors);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
m_pixf->blend_color_vspan(y, x, len, colors, covers, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_color_vspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
m_pixf->blend_color_hspan(y, x, len, colors, covers, cover);
}
private:
pixfmt_type* m_pixf;
};
}
#endif
+755
View File
@@ -0,0 +1,755 @@
//----------------------------------------------------------------------------
// 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.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
// Contact: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED
#define AGG_RASTERIZER_CELLS_AA_INCLUDED
#include <string.h>
#include <math.h>
#include "agg_math.h"
#include "agg_array.h"
namespace agg
{
//-----------------------------------------------------rasterizer_cells_aa
// An internal class that implements the main rasterization algorithm.
// Used in the rasterizer. Should not be used direcly.
template<class Cell> class rasterizer_cells_aa
{
enum cell_block_scale_e
{
cell_block_shift = 12,
cell_block_size = 1 << cell_block_shift,
cell_block_mask = cell_block_size - 1,
cell_block_pool = 256,
cell_block_limit = 1024
};
struct sorted_y
{
unsigned start;
unsigned num;
};
public:
typedef Cell cell_type;
typedef rasterizer_cells_aa<Cell> self_type;
~rasterizer_cells_aa();
rasterizer_cells_aa();
void reset();
void style(const cell_type& style_cell);
void line(int x1, int y1, int x2, int y2);
int min_x() const { return m_min_x; }
int min_y() const { return m_min_y; }
int max_x() const { return m_max_x; }
int max_y() const { return m_max_y; }
void sort_cells();
unsigned total_cells() const
{
return m_num_cells;
}
unsigned scanline_num_cells(unsigned y) const
{
return m_sorted_y[y - m_min_y].num;
}
const cell_type* const* scanline_cells(unsigned y) const
{
return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start;
}
bool sorted() const { return m_sorted; }
private:
rasterizer_cells_aa(const self_type&);
const self_type& operator = (const self_type&);
void set_curr_cell(int x, int y);
void add_curr_cell();
void render_hline(int ey, int x1, int y1, int x2, int y2);
void allocate_block();
private:
unsigned m_num_blocks;
unsigned m_max_blocks;
unsigned m_curr_block;
unsigned m_num_cells;
cell_type** m_cells;
cell_type* m_curr_cell_ptr;
pod_vector<cell_type*> m_sorted_cells;
pod_vector<sorted_y> m_sorted_y;
cell_type m_curr_cell;
cell_type m_style_cell;
int m_min_x;
int m_min_y;
int m_max_x;
int m_max_y;
bool m_sorted;
};
//------------------------------------------------------------------------
template<class Cell>
rasterizer_cells_aa<Cell>::~rasterizer_cells_aa()
{
if(m_num_blocks)
{
cell_type** ptr = m_cells + m_num_blocks - 1;
while(m_num_blocks--)
{
pod_allocator<cell_type>::deallocate(*ptr, cell_block_size);
ptr--;
}
pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
}
}
//------------------------------------------------------------------------
template<class Cell>
rasterizer_cells_aa<Cell>::rasterizer_cells_aa() :
m_num_blocks(0),
m_max_blocks(0),
m_curr_block(0),
m_num_cells(0),
m_cells(0),
m_curr_cell_ptr(0),
m_sorted_cells(),
m_sorted_y(),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
m_max_y(-0x7FFFFFFF),
m_sorted(false)
{
m_style_cell.initial();
m_curr_cell.initial();
}
//------------------------------------------------------------------------
template<class Cell>
void rasterizer_cells_aa<Cell>::reset()
{
m_num_cells = 0;
m_curr_block = 0;
m_curr_cell.initial();
m_style_cell.initial();
m_sorted = false;
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
m_max_y = -0x7FFFFFFF;
}
//------------------------------------------------------------------------
template<class Cell>
AGG_INLINE void rasterizer_cells_aa<Cell>::add_curr_cell()
{
if(m_curr_cell.area | m_curr_cell.cover)
{
if((m_num_cells & cell_block_mask) == 0)
{
if(m_num_blocks >= cell_block_limit) return;
allocate_block();
}
*m_curr_cell_ptr++ = m_curr_cell;
++m_num_cells;
}
}
//------------------------------------------------------------------------
template<class Cell>
AGG_INLINE void rasterizer_cells_aa<Cell>::set_curr_cell(int x, int y)
{
if(m_curr_cell.not_equal(x, y, m_style_cell))
{
add_curr_cell();
m_curr_cell.style(m_style_cell);
m_curr_cell.x = x;
m_curr_cell.y = y;
m_curr_cell.cover = 0;
m_curr_cell.area = 0;
}
}
//------------------------------------------------------------------------
template<class Cell>
AGG_INLINE void rasterizer_cells_aa<Cell>::render_hline(int ey,
int x1, int y1,
int x2, int y2)
{
int ex1 = x1 >> poly_subpixel_shift;
int ex2 = x2 >> poly_subpixel_shift;
int fx1 = x1 & poly_subpixel_mask;
int fx2 = x2 & poly_subpixel_mask;
int delta, p, first, dx;
int incr, lift, mod, rem;
//trivial case. Happens often
if(y1 == y2)
{
set_curr_cell(ex2, ey);
return;
}
//everything is located in a single cell. That is easy!
if(ex1 == ex2)
{
delta = y2 - y1;
m_curr_cell.cover += delta;
m_curr_cell.area += (fx1 + fx2) * delta;
return;
}
//ok, we'll have to render a run of adjacent cells on the same
//hline...
p = (poly_subpixel_scale - fx1) * (y2 - y1);
first = poly_subpixel_scale;
incr = 1;
dx = x2 - x1;
if(dx < 0)
{
p = fx1 * (y2 - y1);
first = 0;
incr = -1;
dx = -dx;
}
delta = p / dx;
mod = p % dx;
if(mod < 0)
{
delta--;
mod += dx;
}
m_curr_cell.cover += delta;
m_curr_cell.area += (fx1 + first) * delta;
ex1 += incr;
set_curr_cell(ex1, ey);
y1 += delta;
if(ex1 != ex2)
{
p = poly_subpixel_scale * (y2 - y1 + delta);
lift = p / dx;
rem = p % dx;
if (rem < 0)
{
lift--;
rem += dx;
}
mod -= dx;
while (ex1 != ex2)
{
delta = lift;
mod += rem;
if(mod >= 0)
{
mod -= dx;
delta++;
}
m_curr_cell.cover += delta;
m_curr_cell.area += poly_subpixel_scale * delta;
y1 += delta;
ex1 += incr;
set_curr_cell(ex1, ey);
}
}
delta = y2 - y1;
m_curr_cell.cover += delta;
m_curr_cell.area += (fx2 + poly_subpixel_scale - first) * delta;
}
//------------------------------------------------------------------------
template<class Cell>
AGG_INLINE void rasterizer_cells_aa<Cell>::style(const cell_type& style_cell)
{
m_style_cell.style(style_cell);
}
//------------------------------------------------------------------------
template<class Cell>
void rasterizer_cells_aa<Cell>::line(int x1, int y1, int x2, int y2)
{
enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift };
int dx = x2 - x1;
if(dx >= dx_limit || dx <= -dx_limit)
{
int cx = (x1 + x2) >> 1;
int cy = (y1 + y2) >> 1;
line(x1, y1, cx, cy);
line(cx, cy, x2, y2);
}
int dy = y2 - y1;
int ex1 = x1 >> poly_subpixel_shift;
int ex2 = x2 >> poly_subpixel_shift;
int ey1 = y1 >> poly_subpixel_shift;
int ey2 = y2 >> poly_subpixel_shift;
int fy1 = y1 & poly_subpixel_mask;
int fy2 = y2 & poly_subpixel_mask;
int x_from, x_to;
int p, rem, mod, lift, delta, first, incr;
if(ex1 < m_min_x) m_min_x = ex1;
if(ex1 > m_max_x) m_max_x = ex1;
if(ey1 < m_min_y) m_min_y = ey1;
if(ey1 > m_max_y) m_max_y = ey1;
if(ex2 < m_min_x) m_min_x = ex2;
if(ex2 > m_max_x) m_max_x = ex2;
if(ey2 < m_min_y) m_min_y = ey2;
if(ey2 > m_max_y) m_max_y = ey2;
set_curr_cell(ex1, ey1);
//everything is on a single hline
if(ey1 == ey2)
{
render_hline(ey1, x1, fy1, x2, fy2);
return;
}
//Vertical line - we have to calculate start and end cells,
//and then - the common values of the area and coverage for
//all cells of the line. We know exactly there's only one
//cell, so, we don't have to call render_hline().
incr = 1;
if(dx == 0)
{
int ex = x1 >> poly_subpixel_shift;
int two_fx = (x1 - (ex << poly_subpixel_shift)) << 1;
int area;
first = poly_subpixel_scale;
if(dy < 0)
{
first = 0;
incr = -1;
}
x_from = x1;
//render_hline(ey1, x_from, fy1, x_from, first);
delta = first - fy1;
m_curr_cell.cover += delta;
m_curr_cell.area += two_fx * delta;
ey1 += incr;
set_curr_cell(ex, ey1);
delta = first + first - poly_subpixel_scale;
area = two_fx * delta;
while(ey1 != ey2)
{
//render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, first);
m_curr_cell.cover = delta;
m_curr_cell.area = area;
ey1 += incr;
set_curr_cell(ex, ey1);
}
//render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, fy2);
delta = fy2 - poly_subpixel_scale + first;
m_curr_cell.cover += delta;
m_curr_cell.area += two_fx * delta;
return;
}
//ok, we have to render several hlines
p = (poly_subpixel_scale - fy1) * dx;
first = poly_subpixel_scale;
if(dy < 0)
{
p = fy1 * dx;
first = 0;
incr = -1;
dy = -dy;
}
delta = p / dy;
mod = p % dy;
if(mod < 0)
{
delta--;
mod += dy;
}
x_from = x1 + delta;
render_hline(ey1, x1, fy1, x_from, first);
ey1 += incr;
set_curr_cell(x_from >> poly_subpixel_shift, ey1);
if(ey1 != ey2)
{
p = poly_subpixel_scale * dx;
lift = p / dy;
rem = p % dy;
if(rem < 0)
{
lift--;
rem += dy;
}
mod -= dy;
while(ey1 != ey2)
{
delta = lift;
mod += rem;
if (mod >= 0)
{
mod -= dy;
delta++;
}
x_to = x_from + delta;
render_hline(ey1, x_from, poly_subpixel_scale - first, x_to, first);
x_from = x_to;
ey1 += incr;
set_curr_cell(x_from >> poly_subpixel_shift, ey1);
}
}
render_hline(ey1, x_from, poly_subpixel_scale - first, x2, fy2);
}
//------------------------------------------------------------------------
template<class Cell>
void rasterizer_cells_aa<Cell>::allocate_block()
{
if(m_curr_block >= m_num_blocks)
{
if(m_num_blocks >= m_max_blocks)
{
cell_type** new_cells =
pod_allocator<cell_type*>::allocate(m_max_blocks +
cell_block_pool);
if(m_cells)
{
memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*));
pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
}
m_cells = new_cells;
m_max_blocks += cell_block_pool;
}
m_cells[m_num_blocks++] =
pod_allocator<cell_type>::allocate(cell_block_size);
}
m_curr_cell_ptr = m_cells[m_curr_block++];
}
//------------------------------------------------------------------------
template <class T> static AGG_INLINE void swap_cells(T* a, T* b)
{
T temp = *a;
*a = *b;
*b = temp;
}
//------------------------------------------------------------------------
enum
{
qsort_threshold = 9
};
//------------------------------------------------------------------------
template<class Cell>
void qsort_cells(Cell** start, unsigned num)
{
Cell** stack[80];
Cell*** top;
Cell** limit;
Cell** base;
limit = start + num;
base = start;
top = stack;
for (;;)
{
int len = int(limit - base);
Cell** i;
Cell** j;
Cell** pivot;
if(len > qsort_threshold)
{
// we use base + len/2 as the pivot
pivot = base + len / 2;
swap_cells(base, pivot);
i = base + 1;
j = limit - 1;
// now ensure that *i <= *base <= *j
if((*j)->x < (*i)->x)
{
swap_cells(i, j);
}
if((*base)->x < (*i)->x)
{
swap_cells(base, i);
}
if((*j)->x < (*base)->x)
{
swap_cells(base, j);
}
for(;;)
{
int x = (*base)->x;
do i++; while( (*i)->x < x );
do j--; while( x < (*j)->x );
if(i > j)
{
break;
}
swap_cells(i, j);
}
swap_cells(base, j);
// now, push the largest sub-array
if(j - base > limit - i)
{
top[0] = base;
top[1] = j;
base = i;
}
else
{
top[0] = i;
top[1] = limit;
limit = j;
}
top += 2;
}
else
{
// the sub-array is small, perform insertion sort
j = base;
i = j + 1;
for(; i < limit; j = i, i++)
{
for(; j[1]->x < (*j)->x; j--)
{
swap_cells(j + 1, j);
if (j == base)
{
break;
}
}
}
if(top > stack)
{
top -= 2;
base = top[0];
limit = top[1];
}
else
{
break;
}
}
}
}
//------------------------------------------------------------------------
template<class Cell>
void rasterizer_cells_aa<Cell>::sort_cells()
{
if(m_sorted) return; //Perform sort only the first time.
add_curr_cell();
m_curr_cell.x = 0x7FFFFFFF;
m_curr_cell.y = 0x7FFFFFFF;
m_curr_cell.cover = 0;
m_curr_cell.area = 0;
if(m_num_cells == 0) return;
// DBG: Check to see if min/max works well.
//for(unsigned nc = 0; nc < m_num_cells; nc++)
//{
// cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask);
// if(cell->x < m_min_x ||
// cell->y < m_min_y ||
// cell->x > m_max_x ||
// cell->y > m_max_y)
// {
// cell = cell; // Breakpoint here
// }
//}
// Allocate the array of cell pointers
m_sorted_cells.allocate(m_num_cells, 16);
// Allocate and zero the Y array
m_sorted_y.allocate(m_max_y - m_min_y + 1, 16);
m_sorted_y.zero();
// Create the Y-histogram (count the numbers of cells for each Y)
cell_type** block_ptr = m_cells;
cell_type* cell_ptr;
unsigned nb = m_num_cells >> cell_block_shift;
unsigned i;
while(nb--)
{
cell_ptr = *block_ptr++;
i = cell_block_size;
while(i--)
{
m_sorted_y[cell_ptr->y - m_min_y].start++;
++cell_ptr;
}
}
cell_ptr = *block_ptr++;
i = m_num_cells & cell_block_mask;
while(i--)
{
m_sorted_y[cell_ptr->y - m_min_y].start++;
++cell_ptr;
}
// Convert the Y-histogram into the array of starting indexes
unsigned start = 0;
for(i = 0; i < m_sorted_y.size(); i++)
{
unsigned v = m_sorted_y[i].start;
m_sorted_y[i].start = start;
start += v;
}
// Fill the cell pointer array sorted by Y
block_ptr = m_cells;
nb = m_num_cells >> cell_block_shift;
while(nb--)
{
cell_ptr = *block_ptr++;
i = cell_block_size;
while(i--)
{
sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
++curr_y.num;
++cell_ptr;
}
}
cell_ptr = *block_ptr++;
i = m_num_cells & cell_block_mask;
while(i--)
{
sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
++curr_y.num;
++cell_ptr;
}
// Finally arrange the X-arrays
for(i = 0; i < m_sorted_y.size(); i++)
{
const sorted_y& curr_y = m_sorted_y[i];
if(curr_y.num)
{
qsort_cells(m_sorted_cells.data() + curr_y.start, curr_y.num);
}
}
m_sorted = true;
}
//------------------------------------------------------scanline_hit_test
class scanline_hit_test
{
public:
scanline_hit_test(int x) : m_x(x), m_hit(false) {}
void reset_spans() {}
void finalize(int) {}
void add_cell(int x, int)
{
if(m_x == x) m_hit = true;
}
void add_span(int x, int len, int)
{
if(m_x >= x && m_x < x+len) m_hit = true;
}
unsigned num_spans() const { return 1; }
bool hit() const { return m_hit; }
private:
int m_x;
bool m_hit;
};
}
#endif
+675
View File
@@ -0,0 +1,675 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// 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.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
// Contact: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_COMPOUND_AA_INCLUDED
#define AGG_RASTERIZER_COMPOUND_AA_INCLUDED
#include "agg_rasterizer_cells_aa.h"
#include "agg_rasterizer_sl_clip.h"
namespace agg
{
//-----------------------------------------------------------cell_style_aa
// A pixel cell. There're no constructors defined and it was done
// intentionally in order to avoid extra overhead when allocating an
// array of cells.
struct cell_style_aa
{
int x;
int y;
int cover;
int area;
int16 left, right;
void initial()
{
x = 0x7FFFFFFF;
y = 0x7FFFFFFF;
cover = 0;
area = 0;
left = -1;
right = -1;
}
void style(const cell_style_aa& c)
{
left = c.left;
right = c.right;
}
int not_equal(int ex, int ey, const cell_style_aa& c) const
{
return (ex - x) | (ey - y) | (left - c.left) | (right - c.right);
}
};
//==================================================rasterizer_compound_aa
template<class Clip=rasterizer_sl_clip_int> class rasterizer_compound_aa
{
struct style_info
{
unsigned start_cell;
unsigned num_cells;
int last_x;
};
struct cell_info
{
int x, area, cover;
};
public:
typedef Clip clip_type;
typedef typename Clip::conv_type conv_type;
typedef typename Clip::coord_type coord_type;
enum aa_scale_e
{
aa_shift = 8,
aa_scale = 1 << aa_shift,
aa_mask = aa_scale - 1,
aa_scale2 = aa_scale * 2,
aa_mask2 = aa_scale2 - 1
};
//--------------------------------------------------------------------
rasterizer_compound_aa() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
m_styles(), // Active Styles
m_ast(), // Active Style Table (unique values)
m_asm(), // Active Style Mask
m_cells(),
m_cover_buf(),
m_master_alpha(),
m_min_style(0x7FFFFFFF),
m_max_style(-0x7FFFFFFF),
m_start_x(0),
m_start_y(0),
m_scan_y(0x7FFFFFFF),
m_sl_start(0),
m_sl_len(0)
{}
//--------------------------------------------------------------------
void reset();
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
void master_alpha(int style, double alpha);
//--------------------------------------------------------------------
void styles(int left, int right);
void move_to(int x, int y);
void line_to(int x, int y);
void move_to_d(double x, double y);
void line_to_d(double x, double y);
void add_vertex(double x, double y, unsigned cmd);
void edge(int x1, int y1, int x2, int y2);
void edge_d(double x1, double y1, double x2, double y2);
//-------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(path_id);
if(m_outline.sorted()) reset();
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x(); }
int min_y() const { return m_outline.min_y(); }
int max_x() const { return m_outline.max_x(); }
int max_y() const { return m_outline.max_y(); }
int min_style() const { return m_min_style; }
int max_style() const { return m_max_style; }
//--------------------------------------------------------------------
void sort();
bool rewind_scanlines();
unsigned sweep_styles();
int scanline_start() const { return m_sl_start; }
unsigned scanline_length() const { return m_sl_len; }
unsigned style(unsigned style_idx) const;
cover_type* allocate_cover_buffer(unsigned len);
//--------------------------------------------------------------------
bool navigate_scanline(int y);
bool hit_test(int tx, int ty);
//--------------------------------------------------------------------
AGG_INLINE unsigned calculate_alpha(int area, unsigned master_alpha) const
{
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
cover &= aa_mask2;
if(cover > aa_scale)
{
cover = aa_scale2 - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
return (cover * master_alpha + aa_mask) >> aa_shift;
}
//--------------------------------------------------------------------
// Sweeps one scanline with one style index. The style ID can be
// determined by calling style().
template<class Scanline> bool sweep_scanline(Scanline& sl, int style_idx)
{
int scan_y = m_scan_y - 1;
if(scan_y > m_outline.max_y()) return false;
sl.reset_spans();
unsigned master_alpha = aa_mask;
if(style_idx < 0)
{
style_idx = 0;
}
else
{
style_idx++;
master_alpha = m_master_alpha[m_ast[style_idx] + m_min_style - 1];
}
const style_info& st = m_styles[m_ast[style_idx]];
unsigned num_cells = st.num_cells;
cell_info* cell = &m_cells[st.start_cell];
int cover = 0;
while(num_cells--)
{
unsigned alpha;
int x = cell->x;
int area = cell->area;
cover += cell->cover;
++cell;
if(area)
{
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area,
master_alpha);
sl.add_cell(x, alpha);
x++;
}
if(num_cells && cell->x > x)
{
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1),
master_alpha);
if(alpha)
{
sl.add_span(x, cell->x - x, alpha);
}
}
}
if(sl.num_spans() == 0) return false;
sl.finalize(scan_y);
return true;
}
private:
void add_style(int style_id);
void allocate_master_alpha();
//--------------------------------------------------------------------
// Disable copying
rasterizer_compound_aa(const rasterizer_compound_aa<Clip>&);
const rasterizer_compound_aa<Clip>&
operator = (const rasterizer_compound_aa<Clip>&);
private:
rasterizer_cells_aa<cell_style_aa> m_outline;
clip_type m_clipper;
filling_rule_e m_filling_rule;
pod_vector<style_info> m_styles; // Active Styles
pod_vector<unsigned> m_ast; // Active Style Table (unique values)
pod_vector<int8u> m_asm; // Active Style Mask
pod_vector<cell_info> m_cells;
pod_vector<cover_type> m_cover_buf;
pod_bvector<unsigned> m_master_alpha;
int m_min_style;
int m_max_style;
coord_type m_start_x;
coord_type m_start_y;
int m_scan_y;
int m_sl_start;
unsigned m_sl_len;
};
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::reset()
{
m_outline.reset();
m_min_style = 0x7FFFFFFF;
m_max_style = -0x7FFFFFFF;
m_scan_y = 0x7FFFFFFF;
m_sl_start = 0;
m_sl_len = 0;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::clip_box(double x1, double y1,
double x2, double y2)
{
reset();
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
conv_type::upscale(x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::reset_clipping()
{
reset();
m_clipper.reset_clipping();
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::styles(int left, int right)
{
cell_style_aa cell;
cell.initial();
cell.left = (int16)left;
cell.right = (int16)right;
m_outline.style(cell);
if(left >= 0 && left < m_min_style) m_min_style = left;
if(left >= 0 && left > m_max_style) m_max_style = left;
if(right >= 0 && right < m_min_style) m_min_style = right;
if(right >= 0 && right > m_max_style) m_max_style = right;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::move_to(int x, int y)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_start_y = conv_type::downscale(y));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::line_to(int x, int y)
{
m_clipper.line_to(m_outline,
conv_type::downscale(x),
conv_type::downscale(y));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::move_to_d(double x, double y)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(m_start_x = conv_type::upscale(x),
m_start_y = conv_type::upscale(y));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::line_to_d(double x, double y)
{
m_clipper.line_to(m_outline,
conv_type::upscale(x),
conv_type::upscale(y));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
move_to_d(x, y);
}
else
if(is_vertex(cmd))
{
line_to_d(x, y);
}
else
if(is_close(cmd))
{
m_clipper.line_to(m_outline, m_start_x, m_start_y);
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::edge(int x1, int y1, int x2, int y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
m_clipper.line_to(m_outline,
conv_type::downscale(x2),
conv_type::downscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
m_clipper.line_to(m_outline,
conv_type::upscale(x2),
conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE void rasterizer_compound_aa<Clip>::sort()
{
m_outline.sort_cells();
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_compound_aa<Clip>::rewind_scanlines()
{
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
{
return false;
}
if(m_max_style < m_min_style)
{
return false;
}
m_scan_y = m_outline.min_y();
m_styles.allocate(m_max_style - m_min_style + 2, 128);
allocate_master_alpha();
return true;
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE void rasterizer_compound_aa<Clip>::add_style(int style_id)
{
if(style_id < 0) style_id = 0;
else style_id -= m_min_style - 1;
unsigned nbyte = style_id >> 3;
unsigned mask = 1 << (style_id & 7);
style_info* style = &m_styles[style_id];
if((m_asm[nbyte] & mask) == 0)
{
m_ast.add(style_id);
m_asm[nbyte] |= mask;
style->start_cell = 0;
style->num_cells = 0;
style->last_x = -0x7FFFFFFF;
}
++style->start_cell;
}
//------------------------------------------------------------------------
// Returns the number of styles
template<class Clip>
unsigned rasterizer_compound_aa<Clip>::sweep_styles()
{
for(;;)
{
if(m_scan_y > m_outline.max_y()) return 0;
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
const cell_style_aa* const* cells = m_outline.scanline_cells(m_scan_y);
unsigned num_styles = m_max_style - m_min_style + 2;
const cell_style_aa* curr_cell;
unsigned style_id;
style_info* style;
cell_info* cell;
m_cells.allocate(num_cells * 2, 256); // Each cell can have two styles
m_ast.capacity(num_styles, 64);
m_asm.allocate((num_styles + 7) >> 3, 8);
m_asm.zero();
if(num_cells)
{
// Pre-add zero (for no-fill style, that is, -1).
// We need that to ensure that the "-1 style" would go first.
m_asm[0] |= 1;
m_ast.add(0);
style = &m_styles[0];
style->start_cell = 0;
style->num_cells = 0;
style->last_x = -0x7FFFFFFF;
m_sl_start = cells[0]->x;
m_sl_len = cells[num_cells-1]->x - m_sl_start + 1;
while(num_cells--)
{
curr_cell = *cells++;
add_style(curr_cell->left);
add_style(curr_cell->right);
}
// Convert the Y-histogram into the array of starting indexes
unsigned i;
unsigned start_cell = 0;
for(i = 0; i < m_ast.size(); i++)
{
style_info& st = m_styles[m_ast[i]];
unsigned v = st.start_cell;
st.start_cell = start_cell;
start_cell += v;
}
cells = m_outline.scanline_cells(m_scan_y);
num_cells = m_outline.scanline_num_cells(m_scan_y);
while(num_cells--)
{
curr_cell = *cells++;
style_id = (curr_cell->left < 0) ? 0 :
curr_cell->left - m_min_style + 1;
style = &m_styles[style_id];
if(curr_cell->x == style->last_x)
{
cell = &m_cells[style->start_cell + style->num_cells - 1];
cell->area += curr_cell->area;
cell->cover += curr_cell->cover;
}
else
{
cell = &m_cells[style->start_cell + style->num_cells];
cell->x = curr_cell->x;
cell->area = curr_cell->area;
cell->cover = curr_cell->cover;
style->last_x = curr_cell->x;
style->num_cells++;
}
style_id = (curr_cell->right < 0) ? 0 :
curr_cell->right - m_min_style + 1;
style = &m_styles[style_id];
if(curr_cell->x == style->last_x)
{
cell = &m_cells[style->start_cell + style->num_cells - 1];
cell->area -= curr_cell->area;
cell->cover -= curr_cell->cover;
}
else
{
cell = &m_cells[style->start_cell + style->num_cells];
cell->x = curr_cell->x;
cell->area = -curr_cell->area;
cell->cover = -curr_cell->cover;
style->last_x = curr_cell->x;
style->num_cells++;
}
}
}
if(m_ast.size() > 1) break;
++m_scan_y;
}
++m_scan_y;
range_adaptor<pod_vector<unsigned> > ra(m_ast, 1, m_ast.size() - 1);
quick_sort(ra, unsigned_greater);
return m_ast.size() - 1;
}
//------------------------------------------------------------------------
// Returns style ID depending of the existing style index
template<class Clip>
AGG_INLINE
unsigned rasterizer_compound_aa<Clip>::style(unsigned style_idx) const
{
return m_ast[style_idx + 1] + m_min_style - 1;
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_compound_aa<Clip>::navigate_scanline(int y)
{
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
{
return false;
}
if(m_max_style < m_min_style)
{
return false;
}
if(y < m_outline.min_y() || y > m_outline.max_y())
{
return false;
}
m_scan_y = y;
m_styles.allocate(m_max_style - m_min_style + 2, 128);
allocate_master_alpha();
return true;
}
//------------------------------------------------------------------------
template<class Clip>
bool rasterizer_compound_aa<Clip>::hit_test(int tx, int ty)
{
if(!navigate_scanline(ty))
{
return false;
}
unsigned num_styles = sweep_styles();
if(num_styles <= 0)
{
return false;
}
scanline_hit_test sl(tx);
sweep_scanline(sl, -1);
return sl.hit();
}
//------------------------------------------------------------------------
template<class Clip>
cover_type* rasterizer_compound_aa<Clip>::allocate_cover_buffer(unsigned len)
{
m_cover_buf.allocate(len, 256);
return &m_cover_buf[0];
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::allocate_master_alpha()
{
while((int)m_master_alpha.size() <= m_max_style)
{
m_master_alpha.add(aa_mask);
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::master_alpha(int style, double alpha)
{
if(style >= 0)
{
while((int)m_master_alpha.size() <= style)
{
m_master_alpha.add(aa_mask);
}
m_master_alpha[style] = uround(alpha * aa_mask);
}
}
}
#endif
+22 -10
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -23,19 +23,26 @@ namespace agg
template<class Renderer> class rasterizer_outline
{
public:
rasterizer_outline(Renderer& ren) : m_ren(&ren), m_start_x(0), m_start_y(0)
{
}
rasterizer_outline(Renderer& ren) :
m_ren(&ren),
m_start_x(0),
m_start_y(0),
m_vertices(0)
{}
void attach(Renderer& ren) { m_ren = &ren; }
//--------------------------------------------------------------------
void move_to(int x, int y)
{
m_vertices = 1;
m_ren->move_to(m_start_x = x, m_start_y = y);
}
//--------------------------------------------------------------------
void line_to(int x, int y)
{
++m_vertices;
m_ren->line_to(x, y);
}
@@ -54,7 +61,11 @@ namespace agg
//--------------------------------------------------------------------
void close()
{
line_to(m_start_x, m_start_y);
if(m_vertices > 2)
{
line_to(m_start_x, m_start_y);
}
m_vertices = 0;
}
//--------------------------------------------------------------------
@@ -80,13 +91,13 @@ namespace agg
//--------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned id=0)
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(id);
vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
@@ -98,13 +109,13 @@ namespace agg
template<class VertexSource, class ColorStorage, class PathId>
void render_all_paths(VertexSource& vs,
const ColorStorage& colors,
const PathId& id,
const PathId& path_id,
unsigned num_paths)
{
for(unsigned i = 0; i < num_paths; i++)
{
m_ren->line_color(colors[i]);
add_path(vs, id[i]);
add_path(vs, path_id[i]);
}
}
@@ -125,6 +136,7 @@ namespace agg
Renderer* m_ren;
int m_start_x;
int m_start_y;
unsigned m_vertices;
};
+189 -103
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -49,16 +49,23 @@ namespace agg
{
double dx = val.x - x;
double dy = val.y - y;
return (len = int(sqrt(dx * dx + dy * dy))) >
(line_subpixel_size + line_subpixel_size / 2);
return (len = uround(sqrt(dx * dx + dy * dy))) >
(line_subpixel_scale + line_subpixel_scale / 2);
}
};
//----------------------------------------------------------outline_aa_join_e
enum outline_aa_join_e
{
outline_no_join, //-----outline_no_join
outline_miter_join, //-----outline_miter_join
outline_round_join, //-----outline_round_join
outline_miter_accurate_join //-----outline_accurate_join
};
//=======================================================rasterizer_outline_aa
template<class Renderer> class rasterizer_outline_aa
template<class Renderer, class Coord=line_coord> class rasterizer_outline_aa
{
private:
//------------------------------------------------------------------------
@@ -79,20 +86,24 @@ namespace agg
typedef vertex_sequence<vertex_type, 6> vertex_storage_type;
rasterizer_outline_aa(Renderer& ren) :
m_ren(ren),
m_accurate_join(m_ren.accurate_join_only()),
m_ren(&ren),
m_line_join(ren.accurate_join_only() ?
outline_miter_accurate_join :
outline_round_join),
m_round_cap(false),
m_start_x(0),
m_start_y(0)
{
}
{}
void attach(Renderer& ren) { m_ren = &ren; }
//------------------------------------------------------------------------
void accurate_join(bool v)
void line_join(outline_aa_join_e join)
{
m_accurate_join = m_ren.accurate_join_only() ? true : v;
m_line_join = m_ren->accurate_join_only() ?
outline_miter_accurate_join :
join;
}
bool accurate_join() const { return m_accurate_join; }
bool line_join() const { return m_line_join; }
//------------------------------------------------------------------------
void round_cap(bool v) { m_round_cap = v; }
@@ -113,13 +124,13 @@ namespace agg
//------------------------------------------------------------------------
void move_to_d(double x, double y)
{
move_to(line_coord(x), line_coord(y));
move_to(Coord::conv(x), Coord::conv(y));
}
//------------------------------------------------------------------------
void line_to_d(double x, double y)
{
line_to(line_coord(x), line_coord(y));
line_to(Coord::conv(x), Coord::conv(y));
}
//------------------------------------------------------------------------
@@ -138,7 +149,10 @@ namespace agg
if(is_end_poly(cmd))
{
render(is_closed(cmd));
if(is_closed(cmd)) move_to(m_start_x, m_start_y);
if(is_closed(cmd))
{
move_to(m_start_x, m_start_y);
}
}
else
{
@@ -149,13 +163,13 @@ namespace agg
//------------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned id=0)
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(id);
vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
@@ -168,13 +182,13 @@ namespace agg
template<class VertexSource, class ColorStorage, class PathId>
void render_all_paths(VertexSource& vs,
const ColorStorage& colors,
const PathId& id,
const PathId& path_id,
unsigned num_paths)
{
for(unsigned i = 0; i < num_paths; i++)
{
m_ren.color(colors[i]);
add_path(vs, id[i]);
m_ren->color(colors[i]);
add_path(vs, path_id[i]);
}
}
@@ -185,22 +199,22 @@ namespace agg
unsigned i;
for(i = 0; i < c.num_paths(); i++)
{
m_ren.color(c.color(i));
m_ren->color(c.color(i));
add_path(c, i);
}
}
private:
rasterizer_outline_aa(const rasterizer_outline_aa<Renderer>&);
const rasterizer_outline_aa<Renderer>& operator =
(const rasterizer_outline_aa<Renderer>&);
rasterizer_outline_aa(const rasterizer_outline_aa<Renderer, Coord>&);
const rasterizer_outline_aa<Renderer, Coord>& operator =
(const rasterizer_outline_aa<Renderer, Coord>&);
Renderer& m_ren;
Renderer* m_ren;
vertex_storage_type m_src_vertices;
bool m_accurate_join;
bool m_round_cap;
int m_start_x;
int m_start_y;
outline_aa_join_e m_line_join;
bool m_round_cap;
int m_start_x;
int m_start_y;
};
@@ -211,20 +225,39 @@ namespace agg
//----------------------------------------------------------------------------
template<class Renderer>
void rasterizer_outline_aa<Renderer>::draw(draw_vars& dv, unsigned start, unsigned end)
template<class Renderer, class Coord>
void rasterizer_outline_aa<Renderer, Coord>::draw(draw_vars& dv,
unsigned start,
unsigned end)
{
unsigned i;
const vertex_storage_type::value_type* v;
for(i = start; i < end; i++)
{
if(m_line_join == outline_round_join)
{
dv.xb1 = dv.curr.x1 + (dv.curr.y2 - dv.curr.y1);
dv.yb1 = dv.curr.y1 - (dv.curr.x2 - dv.curr.x1);
dv.xb2 = dv.curr.x2 + (dv.curr.y2 - dv.curr.y1);
dv.yb2 = dv.curr.y2 - (dv.curr.x2 - dv.curr.x1);
}
switch(dv.flags)
{
case 0: m_ren.line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break;
case 1: m_ren.line2(dv.curr, dv.xb2, dv.yb2); break;
case 2: m_ren.line1(dv.curr, dv.xb1, dv.yb1); break;
case 3: m_ren.line0(dv.curr); break;
case 0: m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break;
case 1: m_ren->line2(dv.curr, dv.xb2, dv.yb2); break;
case 2: m_ren->line1(dv.curr, dv.xb1, dv.yb1); break;
case 3: m_ren->line0(dv.curr); break;
}
if(m_line_join == outline_round_join && (dv.flags & 2) == 0)
{
m_ren->pie(dv.curr.x2, dv.curr.y2,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1),
dv.curr.x2 + (dv.next.y2 - dv.next.y1),
dv.curr.y2 - (dv.next.x2 - dv.next.x1));
}
dv.x1 = dv.x2;
@@ -244,20 +277,32 @@ namespace agg
dv.xb1 = dv.xb2;
dv.yb1 = dv.yb2;
if(m_accurate_join)
{
dv.flags = 0;
}
else
switch(m_line_join)
{
case outline_no_join:
dv.flags = 3;
break;
case outline_miter_join:
dv.flags >>= 1;
dv.flags |= ((dv.curr.diagonal_quadrant() ==
dv.next.diagonal_quadrant()) << 1);
}
if((dv.flags & 2) == 0)
{
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
}
break;
if((dv.flags & 2) == 0)
{
case outline_round_join:
dv.flags >>= 1;
dv.flags |= ((dv.curr.diagonal_quadrant() ==
dv.next.diagonal_quadrant()) << 1);
break;
case outline_miter_accurate_join:
dv.flags = 0;
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
break;
}
}
}
@@ -266,8 +311,8 @@ namespace agg
//----------------------------------------------------------------------------
template<class Renderer>
void rasterizer_outline_aa<Renderer>::render(bool close_polygon)
template<class Renderer, class Coord>
void rasterizer_outline_aa<Renderer, Coord>::render(bool close_polygon)
{
m_src_vertices.close(close_polygon);
draw_vars dv;
@@ -311,23 +356,30 @@ namespace agg
dv.xb2 = 0;
dv.yb2 = 0;
if(m_accurate_join)
{
dv.flags = 0;
}
else
switch(m_line_join)
{
case outline_no_join:
dv.flags = 3;
break;
case outline_miter_join:
case outline_round_join:
dv.flags =
(prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
break;
case outline_miter_accurate_join:
dv.flags = 0;
break;
}
if((dv.flags & 1) == 0)
if((dv.flags & 1) == 0 && m_line_join != outline_round_join)
{
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
}
if((dv.flags & 2) == 0)
if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
{
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
}
@@ -354,16 +406,16 @@ namespace agg
line_parameters lp(x1, y1, x2, y2, lprev);
if(m_round_cap)
{
m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
}
m_ren.line3(lp,
x1 + (y2 - y1),
y1 - (x2 - x1),
x2 + (y2 - y1),
y2 - (x2 - x1));
m_ren->line3(lp,
x1 + (y2 - y1),
y1 - (x2 - x1),
x2 + (y2 - y1),
y2 - (x2 - x1));
if(m_round_cap)
{
m_ren.semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
m_ren->semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
}
}
break;
@@ -385,26 +437,35 @@ namespace agg
y3 = v->y;
line_parameters lp1(x1, y1, x2, y2, lprev);
line_parameters lp2(x2, y2, x3, y3, lnext);
bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
if(m_round_cap)
{
m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
}
m_ren.line3(lp1,
x1 + (y2 - y1),
y1 - (x2 - x1),
dv.xb1,
dv.yb1);
m_ren.line3(lp2,
dv.xb1,
dv.yb1,
x3 + (y3 - y2),
y3 - (x3 - x2));
if(m_line_join == outline_round_join)
{
m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
x2 + (y2 - y1), y2 - (x2 - x1));
m_ren->pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1),
x2 + (y3 - y2), y2 - (x3 - x2));
m_ren->line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2),
x3 + (y3 - y2), y3 - (x3 - x2));
}
else
{
bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
dv.xb1, dv.yb1);
m_ren->line3(lp2, dv.xb1, dv.yb1,
x3 + (y3 - y2), y3 - (x3 - x2));
}
if(m_round_cap)
{
m_ren.semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
}
}
break;
@@ -440,37 +501,53 @@ namespace agg
dv.xb2 = 0;
dv.yb2 = 0;
if(m_accurate_join)
{
dv.flags = 0;
}
else
switch(m_line_join)
{
case outline_no_join:
dv.flags = 3;
break;
case outline_miter_join:
case outline_round_join:
dv.flags =
(prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
break;
case outline_miter_accurate_join:
dv.flags = 0;
break;
}
if(m_round_cap)
{
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
}
if((dv.flags & 1) == 0)
{
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
m_ren.line3(prev,
x1 + (y2 - y1),
y1 - (x2 - x1),
dv.xb1,
dv.yb1);
if(m_line_join == outline_round_join)
{
m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
x2 + (y2 - y1), y2 - (x2 - x1));
m_ren->pie(prev.x2, prev.y2,
x2 + (y2 - y1), y2 - (x2 - x1),
dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y1 - (dv.curr.x2 - dv.curr.x1));
}
else
{
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
dv.xb1, dv.yb1);
}
}
else
{
m_ren.line1(prev,
x1 + (y2 - y1),
y1 - (x2 - x1));
m_ren->line1(prev,
x1 + (y2 - y1),
y1 - (x2 - x1));
}
if(m_round_cap)
{
m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
}
if((dv.flags & 2) == 0)
if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
{
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
}
@@ -479,23 +556,32 @@ namespace agg
if((dv.flags & 1) == 0)
{
m_ren.line3(dv.curr,
dv.xb1,
dv.yb1,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
if(m_line_join == outline_round_join)
{
m_ren->line3(dv.curr,
dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y1 - (dv.curr.x2 - dv.curr.x1),
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
else
{
m_ren->line3(dv.curr, dv.xb1, dv.yb1,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
}
else
{
m_ren.line2(dv.curr,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
m_ren->line2(dv.curr,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
if(m_round_cap)
{
m_ren.semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
m_ren->semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
}
+260 -494
View File
@@ -1,12 +1,14 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
@@ -17,43 +19,24 @@
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Class rasterizer_scanline_aa
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED
#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED
#include <string.h>
#include <math.h>
#include "agg_basics.h"
#include "agg_math.h"
#include "agg_rasterizer_cells_aa.h"
#include "agg_rasterizer_sl_clip.h"
#include "agg_gamma_functions.h"
#include "agg_clip_liang_barsky.h"
#include "agg_render_scanlines.h"
namespace agg
{
//------------------------------------------------------------------------
// These constants determine the subpixel accuracy, to be more precise,
// the number of bits of the fractional part of the coordinates.
// The possible coordinate capacity in bits can be calculated by formula:
// sizeof(int) * 8 - poly_base_shift * 2, i.e, for 32-bit integers and
// 8-bits fractional part the capacity is 16 bits or [-32768...32767].
enum
{
poly_base_shift = 8, //----poly_base_shift
poly_base_size = 1 << poly_base_shift, //----poly_base_size
poly_base_mask = poly_base_size - 1 //----poly_base_mask
};
//--------------------------------------------------------------poly_coord
inline int poly_coord(double c)
{
return int(c * poly_base_size);
}
//-----------------------------------------------------------------cell_aa
// A pixel cell. There're no constructors defined and it was done
@@ -61,90 +44,25 @@ namespace agg
// array of cells.
struct cell_aa
{
int16 x;
int16 y;
int packed_coord;
int cover;
int area;
int x;
int y;
int cover;
int area;
void set(int x, int y, int c, int a);
void set_coord(int x, int y);
void set_cover(int c, int a);
void add_cover(int c, int a);
};
//--------------------------------------------------------------outline_aa
// An internal class that implements the main rasterization algorithm.
// Used in the rasterizer. Should not be used direcly.
class outline_aa
{
enum
void initial()
{
cell_block_shift = 12,
cell_block_size = 1 << cell_block_shift,
cell_block_mask = cell_block_size - 1,
cell_block_pool = 256,
cell_block_limit = 1024
};
x = 0x7FFFFFFF;
y = 0x7FFFFFFF;
cover = 0;
area = 0;
}
public:
void style(const cell_aa&) {}
~outline_aa();
outline_aa();
void reset();
void move_to(int x, int y);
void line_to(int x, int y);
int min_x() const { return m_min_x; }
int min_y() const { return m_min_y; }
int max_x() const { return m_max_x; }
int max_y() const { return m_max_y; }
const cell_aa* const* cells();
unsigned num_cells() { cells(); return m_num_cells; }
bool sorted() const { return m_sorted; }
private:
outline_aa(const outline_aa&);
const outline_aa& operator = (const outline_aa&);
void set_cur_cell(int x, int y);
void add_cur_cell();
void sort_cells();
void render_hline(int ey, int x1, int y1, int x2, int y2);
void render_line(int x1, int y1, int x2, int y2);
void allocate_block();
static void qsort_cells(cell_aa** start, unsigned num);
private:
unsigned m_num_blocks;
unsigned m_max_blocks;
unsigned m_cur_block;
unsigned m_num_cells;
cell_aa** m_cells;
cell_aa* m_cur_cell_ptr;
cell_aa** m_sorted_cells;
unsigned m_sorted_size;
cell_aa m_cur_cell;
int m_cur_x;
int m_cur_y;
int m_min_x;
int m_min_y;
int m_max_x;
int m_max_y;
bool m_sorted;
};
//----------------------------------------------------------filling_rule_e
enum filling_rule_e
{
fill_non_zero,
fill_even_odd
int not_equal(int ex, int ey, const cell_aa&) const
{
return (ex - x) | (ey - y);
}
};
@@ -152,7 +70,7 @@ namespace agg
// Polygon rasterizer that is used to render filled polygons with
// high-quality Anti-Aliasing. Internally, by default, the class uses
// integer coordinates in format 24.8, i.e. 24 bits for integer part
// and 8 bits for fractional - see poly_base_shift. This class can be
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
// used in the following way:
//
// 1. filling_rule(filling_rule_e ft) - optional.
@@ -179,79 +97,72 @@ namespace agg
//
// filling_rule() and gamma() can be called anytime before "sweeping".
//------------------------------------------------------------------------
template<unsigned XScale=1, unsigned AA_Shift=8> class rasterizer_scanline_aa
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
{
enum status
{
status_initial,
status_move_to,
status_line_to,
status_closed
};
struct iterator
{
const cell_aa* const* cells;
int cover;
int last_y;
};
public:
enum
typedef Clip clip_type;
typedef typename Clip::conv_type conv_type;
typedef typename Clip::coord_type coord_type;
enum aa_scale_e
{
aa_shift = AA_Shift,
aa_num = 1 << aa_shift,
aa_mask = aa_num - 1,
aa_2num = aa_num * 2,
aa_2mask = aa_2num - 1
aa_shift = 8,
aa_scale = 1 << aa_shift,
aa_mask = aa_scale - 1,
aa_scale2 = aa_scale * 2,
aa_mask2 = aa_scale2 - 1
};
//--------------------------------------------------------------------
rasterizer_scanline_aa() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
m_clipped_start_x(0),
m_clipped_start_y(0),
m_auto_close(true),
m_start_x(0),
m_start_y(0),
m_prev_x(0),
m_prev_y(0),
m_prev_flags(0),
m_status(status_initial),
m_clipping(false)
m_status(status_initial)
{
int i;
for(i = 0; i < aa_num; i++) m_gamma[i] = i;
for(i = 0; i < aa_scale; i++) m_gamma[i] = i;
}
//--------------------------------------------------------------------
template<class GammaF>
rasterizer_scanline_aa(const GammaF& gamma_function) :
m_outline(),
m_clipper(m_outline),
m_filling_rule(fill_non_zero),
m_clipped_start_x(0),
m_clipped_start_y(0),
m_auto_close(true),
m_start_x(0),
m_start_y(0),
m_prev_x(0),
m_prev_y(0),
m_prev_flags(0),
m_status(status_initial),
m_clipping(false)
m_status(status_initial)
{
gamma(gamma_function);
}
//--------------------------------------------------------------------
void reset();
void filling_rule(filling_rule_e filling_rule);
void clip_box(double x1, double y1, double x2, double y2);
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
void auto_close(bool flag) { m_auto_close = flag; }
//--------------------------------------------------------------------
template<class GammaF> void gamma(const GammaF& gamma_function)
{
int i;
for(i = 0; i < aa_num; i++)
for(i = 0; i < aa_scale; i++)
{
m_gamma[i] = int(floor(gamma_function(double(i) / aa_mask) * aa_mask + 0.5));
m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask);
}
}
@@ -262,12 +173,31 @@ namespace agg
}
//--------------------------------------------------------------------
void add_vertex(double x, double y, unsigned cmd);
void move_to(int x, int y);
void line_to(int x, int y);
void close_polygon();
void move_to_d(double x, double y);
void line_to_d(double x, double y);
void close_polygon();
void add_vertex(double x, double y, unsigned cmd);
void edge(int x1, int y1, int x2, int y2);
void edge_d(double x1, double y1, double x2, double y2);
//-------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(path_id);
if(m_outline.sorted()) reset();
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x(); }
@@ -276,182 +206,107 @@ namespace agg
int max_y() const { return m_outline.max_y(); }
//--------------------------------------------------------------------
unsigned calculate_alpha(int area) const
void sort();
bool rewind_scanlines();
bool navigate_scanline(int y);
//--------------------------------------------------------------------
AGG_INLINE unsigned calculate_alpha(int area) const
{
int cover = area >> (poly_base_shift*2 + 1 - aa_shift);
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
cover &= aa_2mask;
if(cover > aa_num)
cover &= aa_mask2;
if(cover > aa_scale)
{
cover = aa_2num - cover;
cover = aa_scale2 - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
return m_gamma[cover];
}
//--------------------------------------------------------------------
void sort()
{
m_outline.cells();
}
//--------------------------------------------------------------------
bool rewind_scanlines()
{
close_polygon();
m_iterator.cells = m_outline.cells();
if(m_outline.num_cells() == 0)
{
return false;
}
m_iterator.cover = 0;
m_iterator.last_y = (*m_iterator.cells)->y;
return true;
}
//--------------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
sl.reset_spans();
for(;;)
{
const cell_aa* cur_cell = *m_iterator.cells;
if(cur_cell == 0) return false;
++m_iterator.cells;
m_iterator.last_y = cur_cell->y;
if(m_scan_y > m_outline.max_y()) return false;
sl.reset_spans();
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
int cover = 0;
for(;;)
while(num_cells)
{
int coord = cur_cell->packed_coord;
int area = cur_cell->area;
int last_x = cur_cell->x;
const cell_aa* cur_cell = *cells;
int x = cur_cell->x;
int area = cur_cell->area;
unsigned alpha;
m_iterator.cover += cur_cell->cover;
cover += cur_cell->cover;
//accumulate all cells with the same coordinates
for(; (cur_cell = *m_iterator.cells) != 0; ++m_iterator.cells)
//accumulate all cells with the same X
while(--num_cells)
{
if(cur_cell->packed_coord != coord) break;
area += cur_cell->area;
m_iterator.cover += cur_cell->cover;
cur_cell = *++cells;
if(cur_cell->x != x) break;
area += cur_cell->area;
cover += cur_cell->cover;
}
int alpha;
if(cur_cell == 0 || cur_cell->y != m_iterator.last_y)
{
if(area)
{
alpha = calculate_alpha((m_iterator.cover << (poly_base_shift + 1)) - area);
if(alpha)
{
sl.add_cell(last_x, alpha);
}
++last_x;
}
break;
}
++m_iterator.cells;
if(area)
{
alpha = calculate_alpha((m_iterator.cover << (poly_base_shift + 1)) - area);
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
if(alpha)
{
sl.add_cell(last_x, alpha);
sl.add_cell(x, alpha);
}
++last_x;
x++;
}
if(cur_cell->x > last_x)
if(num_cells && cur_cell->x > x)
{
alpha = calculate_alpha(m_iterator.cover << (poly_base_shift + 1));
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
if(alpha)
{
sl.add_span(last_x, cur_cell->x - last_x, alpha);
sl.add_span(x, cur_cell->x - x, alpha);
}
}
}
if(sl.num_spans())
{
sl.finalize(m_iterator.last_y);
break;
}
if(sl.num_spans()) break;
++m_scan_y;
}
sl.finalize(m_scan_y);
++m_scan_y;
return true;
}
//--------------------------------------------------------------------
bool hit_test(int tx, int ty);
//--------------------------------------------------------------------
void add_xy(const double* x, const double* y, unsigned n)
{
if(n > 2)
{
move_to_d(*x++, *y++);
--n;
do
{
line_to_d(*x++, *y++);
}
while(--n);
}
}
//-------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
}
}
private:
//--------------------------------------------------------------------
// Disable copying
rasterizer_scanline_aa(const rasterizer_scanline_aa<XScale, AA_Shift>&);
const rasterizer_scanline_aa<XScale, AA_Shift>&
operator = (const rasterizer_scanline_aa<XScale, AA_Shift>&);
//--------------------------------------------------------------------
void move_to_no_clip(int x, int y);
void line_to_no_clip(int x, int y);
void close_polygon_no_clip();
void clip_segment(int x, int y);
rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&);
const rasterizer_scanline_aa<Clip>&
operator = (const rasterizer_scanline_aa<Clip>&);
private:
outline_aa m_outline;
int m_gamma[aa_num];
rasterizer_cells_aa<cell_aa> m_outline;
clip_type m_clipper;
int m_gamma[aa_scale];
filling_rule_e m_filling_rule;
int m_clipped_start_x;
int m_clipped_start_y;
int m_start_x;
int m_start_y;
int m_prev_x;
int m_prev_y;
unsigned m_prev_flags;
bool m_auto_close;
coord_type m_start_x;
coord_type m_start_y;
unsigned m_status;
rect m_clip_box;
bool m_clipping;
iterator m_iterator;
int m_scan_y;
};
@@ -463,277 +318,188 @@ namespace agg
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::reset()
template<class Clip>
void rasterizer_scanline_aa<Clip>::reset()
{
m_outline.reset();
m_status = status_initial;
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::filling_rule(filling_rule_e filling_rule)
template<class Clip>
void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::clip_box(double x1, double y1, double x2, double y2)
template<class Clip>
void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1,
double x2, double y2)
{
reset();
m_clip_box = rect(poly_coord(x1), poly_coord(y1),
poly_coord(x2), poly_coord(y2));
m_clip_box.normalize();
m_clipping = true;
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
conv_type::upscale(x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::reset_clipping()
template<class Clip>
void rasterizer_scanline_aa<Clip>::reset_clipping()
{
reset();
m_clipping = false;
m_clipper.reset_clipping();
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::move_to_no_clip(int x, int y)
template<class Clip>
void rasterizer_scanline_aa<Clip>::close_polygon()
{
if(m_status == status_line_to)
{
close_polygon_no_clip();
}
m_outline.move_to(x * XScale, y);
m_clipped_start_x = x;
m_clipped_start_y = y;
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::line_to_no_clip(int x, int y)
{
if(m_status != status_initial)
{
m_outline.line_to(x * XScale, y);
m_status = status_line_to;
}
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::close_polygon_no_clip()
{
if(m_status == status_line_to)
{
m_outline.line_to(m_clipped_start_x * XScale, m_clipped_start_y);
m_clipper.line_to(m_outline, m_start_x, m_start_y);
m_status = status_closed;
}
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::clip_segment(int x, int y)
template<class Clip>
void rasterizer_scanline_aa<Clip>::move_to(int x, int y)
{
unsigned flags = clipping_flags(x, y, m_clip_box);
if(m_prev_flags == flags)
{
if(flags == 0)
{
if(m_status == status_initial)
{
move_to_no_clip(x, y);
}
else
{
line_to_no_clip(x, y);
}
}
}
else
{
int cx[4];
int cy[4];
unsigned n = clip_liang_barsky(m_prev_x, m_prev_y,
x, y,
m_clip_box,
cx, cy);
const int* px = cx;
const int* py = cy;
while(n--)
{
if(m_status == status_initial)
{
move_to_no_clip(*px++, *py++);
}
else
{
line_to_no_clip(*px++, *py++);
}
}
}
m_prev_flags = flags;
m_prev_x = x;
m_prev_y = y;
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_start_y = conv_type::downscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::line_to(int x, int y)
{
m_clipper.line_to(m_outline,
conv_type::downscale(x),
conv_type::downscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::add_vertex(double x, double y, unsigned cmd)
template<class Clip>
void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::upscale(x),
m_start_y = conv_type::upscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
{
m_clipper.line_to(m_outline,
conv_type::upscale(x),
conv_type::upscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
move_to_d(x, y);
}
else
if(is_vertex(cmd))
{
line_to_d(x, y);
}
else
if(is_close(cmd))
{
close_polygon();
}
else
{
if(is_move_to(cmd))
{
move_to(poly_coord(x), poly_coord(y));
}
else
{
if(is_vertex(cmd))
{
line_to(poly_coord(x), poly_coord(y));
}
}
}
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::move_to(int x, int y)
{
if(m_clipping)
{
if(m_outline.sorted())
{
reset();
}
if(m_status == status_line_to)
{
close_polygon();
}
m_prev_x = m_start_x = x;
m_prev_y = m_start_y = y;
m_status = status_initial;
m_prev_flags = clipping_flags(x, y, m_clip_box);
if(m_prev_flags == 0)
{
move_to_no_clip(x, y);
}
}
else
{
move_to_no_clip(x, y);
}
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::line_to(int x, int y)
{
if(m_clipping)
{
clip_segment(x, y);
}
else
{
line_to_no_clip(x, y);
}
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::close_polygon()
{
if(m_clipping)
{
clip_segment(m_start_x, m_start_y);
}
close_polygon_no_clip();
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::move_to_d(double x, double y)
{
move_to(poly_coord(x), poly_coord(y));
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::line_to_d(double x, double y)
{
line_to(poly_coord(x), poly_coord(y));
}
//------------------------------------------------------------------------
template<unsigned XScale, unsigned AA_Shift>
bool rasterizer_scanline_aa<XScale, AA_Shift>::hit_test(int tx, int ty)
template<class Clip>
void rasterizer_scanline_aa<Clip>::edge(int x1, int y1, int x2, int y2)
{
close_polygon();
const cell_aa* const* cells = m_outline.cells();
if(m_outline.num_cells() == 0) return false;
int cover = 0;
const cell_aa* cur_cell = *cells++;
for(;;)
{
int alpha;
int coord = cur_cell->packed_coord;
int x = cur_cell->x;
int y = cur_cell->y;
if(y > ty) return false;
int area = cur_cell->area;
cover += cur_cell->cover;
while((cur_cell = *cells++) != 0)
{
if(cur_cell->packed_coord != coord) break;
area += cur_cell->area;
cover += cur_cell->cover;
}
if(area)
{
alpha = calculate_alpha((cover << (poly_base_shift + 1)) - area);
if(alpha)
{
if(tx == x && ty == y) return true;
}
x++;
}
if(!cur_cell) break;
if(cur_cell->x > x)
{
alpha = calculate_alpha(cover << (poly_base_shift + 1));
if(alpha)
{
if(ty == y && tx >= x && tx <= cur_cell->x) return true;
}
}
}
return false;
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
m_clipper.line_to(m_outline,
conv_type::downscale(x2),
conv_type::downscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
m_clipper.line_to(m_outline,
conv_type::upscale(x2),
conv_type::upscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::sort()
{
m_outline.sort_cells();
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
{
return false;
}
m_scan_y = m_outline.min_y();
return true;
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y)
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0 ||
y < m_outline.min_y() ||
y > m_outline.max_y())
{
return false;
}
m_scan_y = y;
return true;
}
//------------------------------------------------------------------------
template<class Clip>
bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty)
{
if(!navigate_scanline(ty)) return false;
scanline_hit_test sl(tx);
sweep_scanline(sl);
return sl.hit();
}
}
+351
View File
@@ -0,0 +1,351 @@
//----------------------------------------------------------------------------
// 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED
#define AGG_RASTERIZER_SL_CLIP_INCLUDED
#include "agg_clip_liang_barsky.h"
namespace agg
{
//--------------------------------------------------------poly_max_coord_e
enum poly_max_coord_e
{
poly_max_coord = (1 << 30) - 1 //----poly_max_coord
};
//------------------------------------------------------------ras_conv_int
struct ras_conv_int
{
typedef int coord_type;
static AGG_INLINE int mul_div(double a, double b, double c)
{
return iround(a * b / c);
}
static int xi(int v) { return v; }
static int yi(int v) { return v; }
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
static int downscale(int v) { return v; }
};
//--------------------------------------------------------ras_conv_int_sat
struct ras_conv_int_sat
{
typedef int coord_type;
static AGG_INLINE int mul_div(double a, double b, double c)
{
return saturation<poly_max_coord>::iround(a * b / c);
}
static int xi(int v) { return v; }
static int yi(int v) { return v; }
static int upscale(double v)
{
return saturation<poly_max_coord>::iround(v * poly_subpixel_scale);
}
static int downscale(int v) { return v; }
};
//---------------------------------------------------------ras_conv_int_3x
struct ras_conv_int_3x
{
typedef int coord_type;
static AGG_INLINE int mul_div(double a, double b, double c)
{
return iround(a * b / c);
}
static int xi(int v) { return v * 3; }
static int yi(int v) { return v; }
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
static int downscale(int v) { return v; }
};
//-----------------------------------------------------------ras_conv_dbl
struct ras_conv_dbl
{
typedef double coord_type;
static AGG_INLINE double mul_div(double a, double b, double c)
{
return a * b / c;
}
static int xi(double v) { return iround(v * poly_subpixel_scale); }
static int yi(double v) { return iround(v * poly_subpixel_scale); }
static double upscale(double v) { return v; }
static double downscale(int v) { return v / double(poly_subpixel_scale); }
};
//--------------------------------------------------------ras_conv_dbl_3x
struct ras_conv_dbl_3x
{
typedef double coord_type;
static AGG_INLINE double mul_div(double a, double b, double c)
{
return a * b / c;
}
static int xi(double v) { return iround(v * poly_subpixel_scale * 3); }
static int yi(double v) { return iround(v * poly_subpixel_scale); }
static double upscale(double v) { return v; }
static double downscale(int v) { return v / double(poly_subpixel_scale); }
};
//------------------------------------------------------rasterizer_sl_clip
template<class Conv> class rasterizer_sl_clip
{
public:
typedef Conv conv_type;
typedef typename Conv::coord_type coord_type;
typedef rect_base<coord_type> rect_type;
//--------------------------------------------------------------------
rasterizer_sl_clip() :
m_clip_box(0,0,0,0),
m_x1(0),
m_y1(0),
m_f1(0),
m_clipping(false)
{}
//--------------------------------------------------------------------
void reset_clipping()
{
m_clipping = false;
}
//--------------------------------------------------------------------
void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2)
{
m_clip_box = rect_type(x1, y1, x2, y2);
m_clip_box.normalize();
m_clipping = true;
}
//--------------------------------------------------------------------
void move_to(coord_type x1, coord_type y1)
{
m_x1 = x1;
m_y1 = y1;
if(m_clipping) m_f1 = clipping_flags(x1, y1, m_clip_box);
}
private:
//------------------------------------------------------------------------
template<class Rasterizer>
AGG_INLINE void line_clip_y(Rasterizer& ras,
coord_type x1, coord_type y1,
coord_type x2, coord_type y2,
unsigned f1, unsigned f2) const
{
f1 &= 10;
f2 &= 10;
if((f1 | f2) == 0)
{
// Fully visible
ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
}
else
{
if(f1 == f2)
{
// Invisible by Y
return;
}
coord_type tx1 = x1;
coord_type ty1 = y1;
coord_type tx2 = x2;
coord_type ty2 = y2;
if(f1 & 8) // y1 < clip.y1
{
tx1 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
ty1 = m_clip_box.y1;
}
if(f1 & 2) // y1 > clip.y2
{
tx1 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
ty1 = m_clip_box.y2;
}
if(f2 & 8) // y2 < clip.y1
{
tx2 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
ty2 = m_clip_box.y1;
}
if(f2 & 2) // y2 > clip.y2
{
tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
ty2 = m_clip_box.y2;
}
ras.line(Conv::xi(tx1), Conv::yi(ty1),
Conv::xi(tx2), Conv::yi(ty2));
}
}
public:
//--------------------------------------------------------------------
template<class Rasterizer>
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
{
if(m_clipping)
{
unsigned f2 = clipping_flags(x2, y2, m_clip_box);
if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0)
{
// Invisible by Y
m_x1 = x2;
m_y1 = y2;
m_f1 = f2;
return;
}
coord_type x1 = m_x1;
coord_type y1 = m_y1;
unsigned f1 = m_f1;
coord_type y3, y4;
unsigned f3, f4;
switch(((f1 & 5) << 1) | (f2 & 5))
{
case 0: // Visible by X
line_clip_y(ras, x1, y1, x2, y2, f1, f2);
break;
case 1: // x2 > clip.x2
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
line_clip_y(ras, x1, y1, m_clip_box.x2, y3, f1, f3);
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2);
break;
case 2: // x1 > clip.x2
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2);
break;
case 3: // x1 > clip.x2 && x2 > clip.x2
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y2, f1, f2);
break;
case 4: // x2 < clip.x1
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
line_clip_y(ras, x1, y1, m_clip_box.x1, y3, f1, f3);
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2);
break;
case 6: // x1 > clip.x2 && x2 < clip.x1
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
y4 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
f4 = clipping_flags_y(y4, m_clip_box);
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x1, y4, f3, f4);
line_clip_y(ras, m_clip_box.x1, y4, m_clip_box.x1, y2, f4, f2);
break;
case 8: // x1 < clip.x1
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2);
break;
case 9: // x1 < clip.x1 && x2 > clip.x2
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
y4 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
f4 = clipping_flags_y(y4, m_clip_box);
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x2, y4, f3, f4);
line_clip_y(ras, m_clip_box.x2, y4, m_clip_box.x2, y2, f4, f2);
break;
case 12: // x1 < clip.x1 && x2 < clip.x1
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2);
break;
}
m_f1 = f2;
}
else
{
ras.line(Conv::xi(m_x1), Conv::yi(m_y1),
Conv::xi(x2), Conv::yi(y2));
}
m_x1 = x2;
m_y1 = y2;
}
private:
rect_type m_clip_box;
coord_type m_x1;
coord_type m_y1;
unsigned m_f1;
bool m_clipping;
};
//---------------------------------------------------rasterizer_sl_no_clip
class rasterizer_sl_no_clip
{
public:
typedef ras_conv_int conv_type;
typedef int coord_type;
rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
void reset_clipping() {}
void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2) {}
void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
template<class Rasterizer>
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
{
ras.line(m_x1, m_y1, x2, y2);
m_x1 = x2;
m_y1 = y2;
}
private:
int m_x1, m_y1;
};
// -----rasterizer_sl_clip_int
// -----rasterizer_sl_clip_int_sat
// -----rasterizer_sl_clip_int_3x
// -----rasterizer_sl_clip_dbl
// -----rasterizer_sl_clip_dbl_3x
//------------------------------------------------------------------------
typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int;
typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat;
typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x;
typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl;
typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x;
}
#endif
-66
View File
@@ -1,66 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_RENDER_SCANLINES_INCLUDED
#define AGG_RENDER_SCANLINES_INCLUDED
#include "agg_basics.h"
namespace agg
{
//========================================================render_scanlines
template<class Rasterizer, class Scanline, class Renderer>
void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren)
{
if(ras.rewind_scanlines())
{
sl.reset(ras.min_x(), ras.max_x());
ren.prepare(unsigned(ras.max_x() - ras.min_x() + 2));
while(ras.sweep_scanline(sl))
{
ren.render(sl);
}
}
}
//========================================================render_all_paths
template<class Rasterizer, class Scanline, class Renderer,
class VertexSource, class ColorStorage, class PathId>
void render_all_paths(Rasterizer& ras,
Scanline& sl,
Renderer& r,
VertexSource& vs,
const ColorStorage& as,
const PathId& id,
unsigned num_paths)
{
for(unsigned i = 0; i < num_paths; i++)
{
ras.reset();
ras.add_path(vs, id[i]);
r.color(as[i]);
render_scanlines(ras, sl, r);
}
}
}
#endif
+102 -75
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -32,12 +32,18 @@ namespace agg
public:
typedef PixelFormat pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::row_data row_data;
//--------------------------------------------------------------------
renderer_base() : m_ren(0), m_clip_box(1, 1, 0, 0) {}
renderer_base(pixfmt_type& ren) :
m_ren(&ren),
m_clip_box(0, 0, ren.width() - 1, ren.height() - 1)
{}
void attach(pixfmt_type& ren)
{
m_ren = &ren;
m_clip_box = rect_i(0, 0, ren.width() - 1, ren.height() - 1);
}
//--------------------------------------------------------------------
@@ -51,9 +57,9 @@ namespace agg
//--------------------------------------------------------------------
bool clip_box(int x1, int y1, int x2, int y2)
{
rect cb(x1, y1, x2, y2);
rect_i cb(x1, y1, x2, y2);
cb.normalize();
if(cb.clip(rect(0, 0, width() - 1, height() - 1)))
if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
{
m_clip_box = cb;
return true;
@@ -99,24 +105,20 @@ namespace agg
return x >= m_clip_box.x1 && y >= m_clip_box.y1 &&
x <= m_clip_box.x2 && y <= m_clip_box.y2;
}
//--------------------------------------------------------------------
void first_clip_box() {}
bool next_clip_box() { return false; }
//--------------------------------------------------------------------
const rect& clip_box() const { return m_clip_box; }
int xmin() const { return m_clip_box.x1; }
int ymin() const { return m_clip_box.y1; }
int xmax() const { return m_clip_box.x2; }
int ymax() const { return m_clip_box.y2; }
const rect_i& clip_box() const { return m_clip_box; }
int xmin() const { return m_clip_box.x1; }
int ymin() const { return m_clip_box.y1; }
int xmax() const { return m_clip_box.x2; }
int ymax() const { return m_clip_box.y2; }
//--------------------------------------------------------------------
const rect& bounding_clip_box() const { return m_clip_box; }
int bounding_xmin() const { return m_clip_box.x1; }
int bounding_ymin() const { return m_clip_box.y1; }
int bounding_xmax() const { return m_clip_box.x2; }
int bounding_ymax() const { return m_clip_box.y2; }
const rect_i& bounding_clip_box() const { return m_clip_box; }
int bounding_xmin() const { return m_clip_box.x1; }
int bounding_ymin() const { return m_clip_box.y1; }
int bounding_xmax() const { return m_clip_box.x2; }
int bounding_ymax() const { return m_clip_box.y2; }
//--------------------------------------------------------------------
void clear(const color_type& c)
@@ -131,6 +133,7 @@ namespace agg
}
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
@@ -223,7 +226,7 @@ namespace agg
//--------------------------------------------------------------------
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
{
rect rc(x1, y1, x2, y2);
rect_i rc(x1, y1, x2, y2);
rc.normalize();
if(rc.clip(clip_box()))
{
@@ -239,7 +242,7 @@ namespace agg
void blend_bar(int x1, int y1, int x2, int y2,
const color_type& c, cover_type cover)
{
rect rc(x1, y1, x2, y2);
rect_i rc(x1, y1, x2, y2);
rc.normalize();
if(rc.clip(clip_box()))
{
@@ -255,7 +258,6 @@ namespace agg
}
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, int len,
const color_type& c,
@@ -302,11 +304,58 @@ namespace agg
m_ren->blend_solid_vspan(x, y, len, c, covers);
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y, int len, const color_type* colors)
{
if(y > ymax()) return;
if(y < ymin()) return;
if(x < xmin())
{
int d = xmin() - x;
len -= d;
if(len <= 0) return;
colors += d;
x = xmin();
}
if(x + len > xmax())
{
len = xmax() - x + 1;
if(len <= 0) return;
}
m_ren->copy_color_hspan(x, y, len, colors);
}
//--------------------------------------------------------------------
void copy_color_vspan(int x, int y, int len, const color_type* colors)
{
if(x > xmax()) return;
if(x < xmin()) return;
if(y < ymin())
{
int d = ymin() - y;
len -= d;
if(len <= 0) return;
colors += d;
y = ymin();
}
if(y + len > ymax())
{
len = ymax() - y + 1;
if(len <= 0) return;
}
m_ren->copy_color_vspan(x, y, len, colors);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
cover_type cover = agg::cover_full)
{
if(y > ymax()) return;
if(y < ymin()) return;
@@ -332,7 +381,7 @@ namespace agg
void blend_color_vspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
cover_type cover = agg::cover_full)
{
if(x > xmax()) return;
if(x < xmin()) return;
@@ -355,29 +404,10 @@ namespace agg
}
//--------------------------------------------------------------------
void blend_color_hspan_no_clip(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
rect_i clip_rect_area(rect_i& dst, rect_i& src, int wsrc, int hsrc) const
{
m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
void blend_color_vspan_no_clip(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
rect clip_rect_area(rect& dst, rect& src, int wsrc, int hsrc) const
{
rect rc(0,0,0,0);
rect cb = clip_box();
rect_i rc(0,0,0,0);
rect_i cb = clip_box();
++cb.x2;
++cb.y2;
@@ -417,14 +447,14 @@ namespace agg
return rc;
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& src,
const rect* rect_src_ptr = 0,
template<class RenBuf>
void copy_from(const RenBuf& src,
const rect_i* rect_src_ptr = 0,
int dx = 0,
int dy = 0)
{
rect rsrc(0, 0, src.width(), src.height());
rect_i rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
@@ -434,12 +464,12 @@ namespace agg
}
// Version with xdst, ydst (absolute positioning)
//rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
// Version with dx, dy (relative positioning)
rect rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
@@ -463,16 +493,15 @@ namespace agg
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& src,
const rect* rect_src_ptr = 0,
int dx = 0,
int dy = 0)
const rect_i* rect_src_ptr = 0,
int dx = 0,
int dy = 0,
cover_type cover = agg::cover_full)
{
rect rsrc(0, 0, src.width(), src.height());
rect_i rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
@@ -482,12 +511,11 @@ namespace agg
}
// Version with xdst, ydst (absolute positioning)
//rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
// Version with dx, dy (relative positioning)
rect rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
@@ -500,30 +528,31 @@ namespace agg
}
while(rc.y2 > 0)
{
typename SrcPixelFormatRenderer::row_data span = src.span(rsrc.x1, rsrc.y1);
if(span.ptr)
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
if(rw.ptr)
{
int x1src = rsrc.x1;
int x1dst = rdst.x1;
int len = rc.x2;
if(span.x1 > x1src)
if(rw.x1 > x1src)
{
x1dst += span.x1 - x1src;
len -= span.x1 - x1src;
x1src = span.x1;
x1dst += rw.x1 - x1src;
len -= rw.x1 - x1src;
x1src = rw.x1;
}
if(len > 0)
{
if(x1src + len-1 > span.x2)
if(x1src + len-1 > rw.x2)
{
len -= x1src + len - span.x2 - 1;
len -= x1src + len - rw.x2 - 1;
}
if(len > 0)
{
m_ren->blend_from(src, span.ptr,
m_ren->blend_from(src,
x1dst, rdst.y1,
x1src, rsrc.y1,
len);
len,
cover);
}
}
}
@@ -534,11 +563,9 @@ namespace agg
}
}
private:
pixfmt_type* m_ren;
rect m_clip_box;
rect_i m_clip_box;
};
+4 -5
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -65,13 +65,12 @@ namespace agg
//--------------------------------------------------------------------
renderer_markers(base_ren_type& rbuf) :
base_type(rbuf)
{
}
{}
//--------------------------------------------------------------------
bool visible(int x, int y, int r) const
{
rect rc(x-r, y-r, x+y, y+r);
rect_i rc(x-r, y-r, x+y, y+r);
return rc.clip(base_type::ren().bounding_clip_box());
}
+58 -43
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -33,14 +33,19 @@ namespace agg
public:
typedef PixelFormat pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::row_data row_data;
typedef renderer_base<pixfmt_type> base_ren_type;
//--------------------------------------------------------------------
renderer_mclip(pixfmt_type& ren) :
m_ren(ren),
renderer_mclip(pixfmt_type& pixf) :
m_ren(pixf),
m_curr_cb(0),
m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax())
{}
void attach(pixfmt_type& pixf)
{
m_ren.attach(pixf);
reset_clipping(true);
}
//--------------------------------------------------------------------
@@ -52,18 +57,18 @@ namespace agg
unsigned height() const { return m_ren.height(); }
//--------------------------------------------------------------------
const rect& clip_box() const { return m_ren.clip_box(); }
int xmin() const { return m_ren.xmin(); }
int ymin() const { return m_ren.ymin(); }
int xmax() const { return m_ren.xmax(); }
int ymax() const { return m_ren.ymax(); }
const rect_i& clip_box() const { return m_ren.clip_box(); }
int xmin() const { return m_ren.xmin(); }
int ymin() const { return m_ren.ymin(); }
int xmax() const { return m_ren.xmax(); }
int ymax() const { return m_ren.ymax(); }
//--------------------------------------------------------------------
const rect& bounding_clip_box() const { return m_bounds; }
int bounding_xmin() const { return m_bounds.x1; }
int bounding_ymin() const { return m_bounds.y1; }
int bounding_xmax() const { return m_bounds.x2; }
int bounding_ymax() const { return m_bounds.y2; }
const rect_i& bounding_clip_box() const { return m_bounds; }
int bounding_xmin() const { return m_bounds.x1; }
int bounding_ymin() const { return m_bounds.y1; }
int bounding_xmax() const { return m_bounds.x2; }
int bounding_ymax() const { return m_bounds.y2; }
//--------------------------------------------------------------------
void first_clip_box()
@@ -71,7 +76,7 @@ namespace agg
m_curr_cb = 0;
if(m_clip.size())
{
const rect& cb = m_clip[0];
const rect_i& cb = m_clip[0];
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
}
}
@@ -81,7 +86,7 @@ namespace agg
{
if(++m_curr_cb < m_clip.size())
{
const rect& cb = m_clip[m_curr_cb];
const rect_i& cb = m_clip[m_curr_cb];
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
return true;
}
@@ -100,9 +105,9 @@ namespace agg
//--------------------------------------------------------------------
void add_clip_box(int x1, int y1, int x2, int y2)
{
rect cb(x1, y1, x2, y2);
rect_i cb(x1, y1, x2, y2);
cb.normalize();
if(cb.clip(rect(0, 0, width() - 1, height() - 1)))
if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
{
m_clip.add(cb);
if(cb.x1 < m_bounds.x1) m_bounds.x1 = cb.x1;
@@ -232,7 +237,6 @@ namespace agg
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, int len,
const color_type& c, const cover_type* covers)
@@ -257,6 +261,18 @@ namespace agg
while(next_clip_box());
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y, int len, const color_type* colors)
{
first_clip_box();
do
{
m_ren.copy_color_hspan(x, y, len, colors);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, int len,
const color_type* colors,
@@ -280,32 +296,14 @@ namespace agg
first_clip_box();
do
{
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
m_ren.blend_color_vspan(x, y, len, colors, covers, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_color_hspan_no_clip(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
m_ren.blend_color_hspan_no_clip(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
void blend_color_vspan_no_clip(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
m_ren.blend_color_vspan_no_clip(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
const rect* rc=0,
const rect_i* rc=0,
int x_to=0,
int y_to=0)
{
@@ -316,16 +314,33 @@ namespace agg
}
while(next_clip_box());
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& src,
const rect_i* rect_src_ptr = 0,
int dx = 0,
int dy = 0,
cover_type cover = cover_full)
{
first_clip_box();
do
{
m_ren.blend_from(src, rect_src_ptr, dx, dy, cover);
}
while(next_clip_box());
}
private:
renderer_mclip(const renderer_mclip<PixelFormat>&);
const renderer_mclip<PixelFormat>&
operator = (const renderer_mclip<PixelFormat>&);
base_ren_type m_ren;
pod_deque<rect, 4> m_clip;
unsigned m_curr_cb;
rect m_bounds;
base_ren_type m_ren;
pod_bvector<rect_i, 4> m_clip;
unsigned m_curr_cb;
rect_i m_bounds;
};
+400 -108
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -15,13 +15,14 @@
#ifndef AGG_RENDERER_OUTLINE_AA_INCLUDED
#define AGG_RENDERER_OUTLINE_AA_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
#include "agg_math.h"
#include "agg_line_aa_basics.h"
#include "agg_dda_line.h"
#include "agg_ellipse_bresenham.h"
#include "agg_renderer_base.h"
#include "agg_gamma_functions.h"
#include "agg_clip_liang_barsky.h"
namespace agg
{
@@ -35,8 +36,8 @@ namespace agg
distance_interpolator0(int x1, int y1, int x2, int y2, int x, int y) :
m_dx(line_mr(x2) - line_mr(x1)),
m_dy(line_mr(y2) - line_mr(y1)),
m_dist((line_mr(x + line_subpixel_size/2) - line_mr(x2)) * m_dy -
(line_mr(y + line_subpixel_size/2) - line_mr(y2)) * m_dx)
m_dist((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy -
(line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx)
{
m_dx <<= line_mr_subpixel_shift;
m_dy <<= line_mr_subpixel_shift;
@@ -44,46 +45,7 @@ namespace agg
//---------------------------------------------------------------------
void inc_x() { m_dist += m_dy; }
void dec_x() { m_dist -= m_dy; }
void inc_y() { m_dist -= m_dx; }
void dec_y() { m_dist += m_dx; }
//---------------------------------------------------------------------
void inc_x(int dy)
{
m_dist += m_dy;
if(dy > 0) m_dist -= m_dx;
if(dy < 0) m_dist += m_dx;
}
//---------------------------------------------------------------------
void dec_x(int dy)
{
m_dist -= m_dy;
if(dy > 0) m_dist -= m_dx;
if(dy < 0) m_dist += m_dx;
}
//---------------------------------------------------------------------
void inc_y(int dx)
{
m_dist -= m_dx;
if(dx > 0) m_dist += m_dy;
if(dx < 0) m_dist -= m_dy;
}
void dec_y(int dx)
//---------------------------------------------------------------------
{
m_dist += m_dx;
if(dx > 0) m_dist += m_dy;
if(dx < 0) m_dist -= m_dy;
}
//---------------------------------------------------------------------
int dist() const { return m_dist; }
int dx() const { return m_dx; }
int dy() const { return m_dy; }
int dist() const { return m_dist; }
private:
//---------------------------------------------------------------------
@@ -92,7 +54,44 @@ namespace agg
int m_dist;
};
//==================================================distance_interpolator00
class distance_interpolator00
{
public:
//---------------------------------------------------------------------
distance_interpolator00() {}
distance_interpolator00(int xc, int yc,
int x1, int y1, int x2, int y2,
int x, int y) :
m_dx1(line_mr(x1) - line_mr(xc)),
m_dy1(line_mr(y1) - line_mr(yc)),
m_dx2(line_mr(x2) - line_mr(xc)),
m_dy2(line_mr(y2) - line_mr(yc)),
m_dist1((line_mr(x + line_subpixel_scale/2) - line_mr(x1)) * m_dy1 -
(line_mr(y + line_subpixel_scale/2) - line_mr(y1)) * m_dx1),
m_dist2((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy2 -
(line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx2)
{
m_dx1 <<= line_mr_subpixel_shift;
m_dy1 <<= line_mr_subpixel_shift;
m_dx2 <<= line_mr_subpixel_shift;
m_dy2 <<= line_mr_subpixel_shift;
}
//---------------------------------------------------------------------
void inc_x() { m_dist1 += m_dy1; m_dist2 += m_dy2; }
int dist1() const { return m_dist1; }
int dist2() const { return m_dist2; }
private:
//---------------------------------------------------------------------
int m_dx1;
int m_dy1;
int m_dx2;
int m_dy2;
int m_dist1;
int m_dist2;
};
//===================================================distance_interpolator1
class distance_interpolator1
@@ -103,8 +102,8 @@ namespace agg
distance_interpolator1(int x1, int y1, int x2, int y2, int x, int y) :
m_dx(x2 - x1),
m_dy(y2 - y1),
m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
double(y + line_subpixel_size/2 - y2) * double(m_dx)))
m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
double(y + line_subpixel_scale/2 - y2) * double(m_dx)))
{
m_dx <<= line_subpixel_shift;
m_dy <<= line_subpixel_shift;
@@ -177,11 +176,11 @@ namespace agg
m_dx_start(line_mr(sx) - line_mr(x1)),
m_dy_start(line_mr(sy) - line_mr(y1)),
m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
double(y + line_subpixel_size/2 - y2) * double(m_dx))),
m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
double(y + line_subpixel_scale/2 - y2) * double(m_dx))),
m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start -
(line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start)
m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start -
(line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start)
{
m_dx <<= line_subpixel_shift;
m_dy <<= line_subpixel_shift;
@@ -196,11 +195,11 @@ namespace agg
m_dx_start(line_mr(ex) - line_mr(x2)),
m_dy_start(line_mr(ey) - line_mr(y2)),
m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
double(y + line_subpixel_size/2 - y2) * double(m_dx))),
m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
double(y + line_subpixel_scale/2 - y2) * double(m_dx))),
m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_start -
(line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_start)
m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_start -
(line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_start)
{
m_dx <<= line_subpixel_shift;
m_dy <<= line_subpixel_shift;
@@ -327,14 +326,14 @@ namespace agg
m_dx_end(line_mr(ex) - line_mr(x2)),
m_dy_end(line_mr(ey) - line_mr(y2)),
m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
double(y + line_subpixel_size/2 - y2) * double(m_dx))),
m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
double(y + line_subpixel_scale/2 - y2) * double(m_dx))),
m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start -
(line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start),
m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start -
(line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start),
m_dist_end((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_end -
(line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_end)
m_dist_end((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_end -
(line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_end)
{
m_dx <<= line_subpixel_shift;
m_dy <<= line_subpixel_shift;
@@ -469,7 +468,7 @@ namespace agg
typedef typename Renderer::color_type color_type;
//---------------------------------------------------------------------
enum
enum max_half_width_e
{
max_half_width = 64
};
@@ -490,7 +489,8 @@ namespace agg
m_count((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
abs((lp.x2 >> line_subpixel_shift) - m_x))),
m_width(ren.subpixel_width()),
m_max_extent(m_width >> (line_subpixel_shift - 2)),
//m_max_extent(m_width >> (line_subpixel_shift - 2)),
m_max_extent((m_width + line_subpixel_mask) >> line_subpixel_shift),
m_step(0)
{
agg::dda2_line_interpolator li(0, lp.vertical ?
@@ -499,7 +499,7 @@ namespace agg
lp.len);
unsigned i;
int stop = m_width + line_subpixel_size * 2;
int stop = m_width + line_subpixel_scale * 2;
for(i = 0; i < max_half_width; ++i)
{
m_dist[i] = li.y();
@@ -1259,40 +1259,33 @@ namespace agg
public:
//---------------------------------------------------------------------
typedef int8u value_type;
enum
enum subpixel_scale_e
{
subpixel_shift = line_subpixel_shift,
subpixel_size = 1 << subpixel_shift,
subpixel_mask = subpixel_size - 1
subpixel_scale = 1 << subpixel_shift,
subpixel_mask = subpixel_scale - 1
};
enum
enum aa_scale_e
{
aa_shift = 8,
aa_num = 1 << aa_shift,
aa_mask = aa_num - 1
aa_scale = 1 << aa_shift,
aa_mask = aa_scale - 1
};
//---------------------------------------------------------------------
~line_profile_aa() { delete [] m_profile; }
//---------------------------------------------------------------------
line_profile_aa() :
m_size(0),
m_profile(0),
m_subpixel_width(0),
m_min_width(1.0),
m_smoother_width(1.0)
{
int i;
for(i = 0; i < aa_num; i++) m_gamma[i] = (value_type)i;
for(i = 0; i < aa_scale; i++) m_gamma[i] = (value_type)i;
}
//---------------------------------------------------------------------
template<class GammaF>
line_profile_aa(double w, const GammaF& gamma_function) :
m_size(0),
m_profile(0),
m_subpixel_width(0),
m_min_width(1.0),
m_smoother_width(1.0)
@@ -1309,17 +1302,16 @@ namespace agg
template<class GammaF> void gamma(const GammaF& gamma_function)
{
int i;
for(i = 0; i < aa_num; i++)
for(i = 0; i < aa_scale; i++)
{
m_gamma[i] = value_type(
floor(
gamma_function(double(i) / aa_mask) * aa_mask + 0.5));
uround(gamma_function(double(i) / aa_mask) * aa_mask));
}
}
void width(double w);
unsigned profile_size() const { return m_size; }
unsigned profile_size() const { return m_profile.size(); }
int subpixel_width() const { return m_subpixel_width; }
//---------------------------------------------------------------------
@@ -1329,7 +1321,7 @@ namespace agg
//---------------------------------------------------------------------
value_type value(int dist) const
{
return m_profile[dist + subpixel_size*2];
return m_profile[dist + subpixel_scale*2];
}
private:
@@ -1340,19 +1332,14 @@ namespace agg
void set(double center_width, double smoother_width);
//---------------------------------------------------------------------
unsigned m_size;
value_type* m_profile;
value_type m_gamma[aa_num];
int m_subpixel_width;
double m_min_width;
double m_smoother_width;
pod_array<value_type> m_profile;
value_type m_gamma[aa_scale];
int m_subpixel_width;
double m_min_width;
double m_smoother_width;
};
//======================================================renderer_outline_aa
template<class BaseRenderer> class renderer_outline_aa
{
@@ -1365,9 +1352,11 @@ namespace agg
//---------------------------------------------------------------------
renderer_outline_aa(base_ren_type& ren, const line_profile_aa& prof) :
m_ren(&ren),
m_profile(&prof)
{
}
m_profile(&prof),
m_clip_box(0,0,0,0),
m_clipping(false)
{}
void attach(base_ren_type& ren) { m_ren = &ren; }
//---------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
@@ -1381,6 +1370,17 @@ namespace agg
//---------------------------------------------------------------------
int subpixel_width() const { return m_profile->subpixel_width(); }
//---------------------------------------------------------------------
void reset_clipping() { m_clipping = false; }
void clip_box(double x1, double y1, double x2, double y2)
{
m_clip_box.x1 = line_coord_sat::conv(x1);
m_clip_box.y1 = line_coord_sat::conv(y1);
m_clip_box.x2 = line_coord_sat::conv(x2);
m_clip_box.y2 = line_coord_sat::conv(y2);
m_clipping = true;
}
//---------------------------------------------------------------------
int cover(int d) const
{
@@ -1415,8 +1415,8 @@ namespace agg
int y = y1 << line_subpixel_shift;
int w = subpixel_width();
distance_interpolator0 di(xc1, yc1, xc2, yc2, x, y);
x += line_subpixel_size/2;
y += line_subpixel_size/2;
x += line_subpixel_scale/2;
y += line_subpixel_scale/2;
int x0 = x1;
int dx = x - xc1;
@@ -1430,7 +1430,7 @@ namespace agg
*p1 = (cover_type)cover(d);
}
++p1;
dx += line_subpixel_size;
dx += line_subpixel_scale;
di.inc_x();
}
while(++x1 <= x2);
@@ -1444,6 +1444,8 @@ namespace agg
template<class Cmp>
void semidot(Cmp cmp, int xc1, int yc1, int xc2, int yc2)
{
if(m_clipping && clipping_flags(xc1, yc1, m_clip_box)) return;
int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift);
if(r < 1) r = 1;
ellipse_bresenham_interpolator ei(r, r);
@@ -1473,8 +1475,88 @@ namespace agg
}
//-------------------------------------------------------------------------
void line0(const line_parameters& lp)
void pie_hline(int xc, int yc, int xp1, int yp1, int xp2, int yp2,
int xh1, int yh1, int xh2)
{
if(m_clipping && clipping_flags(xc, yc, m_clip_box)) return;
cover_type covers[line_interpolator_aa_base<self_type>::max_half_width * 2 + 4];
cover_type* p0 = covers;
cover_type* p1 = covers;
int x = xh1 << line_subpixel_shift;
int y = yh1 << line_subpixel_shift;
int w = subpixel_width();
distance_interpolator00 di(xc, yc, xp1, yp1, xp2, yp2, x, y);
x += line_subpixel_scale/2;
y += line_subpixel_scale/2;
int xh0 = xh1;
int dx = x - xc;
int dy = y - yc;
do
{
int d = int(fast_sqrt(dx*dx + dy*dy));
*p1 = 0;
if(di.dist1() <= 0 && di.dist2() > 0 && d <= w)
{
*p1 = (cover_type)cover(d);
}
++p1;
dx += line_subpixel_scale;
di.inc_x();
}
while(++xh1 <= xh2);
m_ren->blend_solid_hspan(xh0, yh1,
unsigned(p1 - p0),
color(),
p0);
}
//-------------------------------------------------------------------------
void pie(int xc, int yc, int x1, int y1, int x2, int y2)
{
int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift);
if(r < 1) r = 1;
ellipse_bresenham_interpolator ei(r, r);
int dx = 0;
int dy = -r;
int dy0 = dy;
int dx0 = dx;
int x = xc >> line_subpixel_shift;
int y = yc >> line_subpixel_shift;
do
{
dx += ei.dx();
dy += ei.dy();
if(dy != dy0)
{
pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y+dy0, x+dx0);
pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y-dy0, x+dx0);
}
dx0 = dx;
dy0 = dy;
++ei;
}
while(dy < 0);
pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y+dy0, x+dx0);
}
//-------------------------------------------------------------------------
void line0_no_clip(const line_parameters& lp)
{
if(lp.len > line_max_length)
{
line_parameters lp1, lp2;
lp.divide(lp1, lp2);
line0_no_clip(lp1);
line0_no_clip(lp2);
return;
}
line_interpolator_aa0<self_type> li(*this, lp);
if(li.count())
{
@@ -1489,10 +1571,118 @@ namespace agg
}
}
//-------------------------------------------------------------------------
void line0(const line_parameters& lp)
{
if(m_clipping)
{
int x1 = lp.x1;
int y1 = lp.y1;
int x2 = lp.x2;
int y2 = lp.y2;
unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
if((flags & 4) == 0)
{
if(flags)
{
line_parameters lp2(x1, y1, x2, y2,
uround(calc_distance(x1, y1, x2, y2)));
line0_no_clip(lp2);
}
else
{
line0_no_clip(lp);
}
}
}
else
{
line0_no_clip(lp);
}
}
//-------------------------------------------------------------------------
void line1_no_clip(const line_parameters& lp, int sx, int sy)
{
if(lp.len > line_max_length)
{
line_parameters lp1, lp2;
lp.divide(lp1, lp2);
line1_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1);
line1_no_clip(lp2, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1));
return;
}
fix_degenerate_bisectrix_start(lp, &sx, &sy);
line_interpolator_aa1<self_type> li(*this, lp, sx, sy);
if(li.vertical())
{
while(li.step_ver());
}
else
{
while(li.step_hor());
}
}
//-------------------------------------------------------------------------
void line1(const line_parameters& lp, int sx, int sy)
{
line_interpolator_aa1<self_type> li(*this, lp, sx, sy);
if(m_clipping)
{
int x1 = lp.x1;
int y1 = lp.y1;
int x2 = lp.x2;
int y2 = lp.y2;
unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
if((flags & 4) == 0)
{
if(flags)
{
line_parameters lp2(x1, y1, x2, y2,
uround(calc_distance(x1, y1, x2, y2)));
if(flags & 1)
{
sx = x1 + (y2 - y1);
sy = y1 - (x2 - x1);
}
else
{
while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
{
sx = (lp.x1 + sx) >> 1;
sy = (lp.y1 + sy) >> 1;
}
}
line1_no_clip(lp2, sx, sy);
}
else
{
line1_no_clip(lp, sx, sy);
}
}
}
else
{
line1_no_clip(lp, sx, sy);
}
}
//-------------------------------------------------------------------------
void line2_no_clip(const line_parameters& lp, int ex, int ey)
{
if(lp.len > line_max_length)
{
line_parameters lp1, lp2;
lp.divide(lp1, lp2);
line2_no_clip(lp1, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1));
line2_no_clip(lp2, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1);
return;
}
fix_degenerate_bisectrix_end(lp, &ex, &ey);
line_interpolator_aa2<self_type> li(*this, lp, ex, ey);
if(li.vertical())
{
while(li.step_ver());
@@ -1506,7 +1696,64 @@ namespace agg
//-------------------------------------------------------------------------
void line2(const line_parameters& lp, int ex, int ey)
{
line_interpolator_aa2<self_type> li(*this, lp, ex, ey);
if(m_clipping)
{
int x1 = lp.x1;
int y1 = lp.y1;
int x2 = lp.x2;
int y2 = lp.y2;
unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
if((flags & 4) == 0)
{
if(flags)
{
line_parameters lp2(x1, y1, x2, y2,
uround(calc_distance(x1, y1, x2, y2)));
if(flags & 2)
{
ex = x2 + (y2 - y1);
ey = y2 - (x2 - x1);
}
else
{
while(abs(ex - lp.x2) + abs(ey - lp.y2) > lp2.len)
{
ex = (lp.x2 + ex) >> 1;
ey = (lp.y2 + ey) >> 1;
}
}
line2_no_clip(lp2, ex, ey);
}
else
{
line2_no_clip(lp, ex, ey);
}
}
}
else
{
line2_no_clip(lp, ex, ey);
}
}
//-------------------------------------------------------------------------
void line3_no_clip(const line_parameters& lp,
int sx, int sy, int ex, int ey)
{
if(lp.len > line_max_length)
{
line_parameters lp1, lp2;
lp.divide(lp1, lp2);
int mx = lp1.x2 + (lp1.y2 - lp1.y1);
int my = lp1.y2 - (lp1.x2 - lp1.x1);
line3_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my);
line3_no_clip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1);
return;
}
fix_degenerate_bisectrix_start(lp, &sx, &sy);
fix_degenerate_bisectrix_end(lp, &ex, &ey);
line_interpolator_aa3<self_type> li(*this, lp, sx, sy, ex, ey);
if(li.vertical())
{
while(li.step_ver());
@@ -1521,21 +1768,66 @@ namespace agg
void line3(const line_parameters& lp,
int sx, int sy, int ex, int ey)
{
line_interpolator_aa3<self_type> li(*this, lp, sx, sy, ex, ey);
if(li.vertical())
if(m_clipping)
{
while(li.step_ver());
int x1 = lp.x1;
int y1 = lp.y1;
int x2 = lp.x2;
int y2 = lp.y2;
unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
if((flags & 4) == 0)
{
if(flags)
{
line_parameters lp2(x1, y1, x2, y2,
uround(calc_distance(x1, y1, x2, y2)));
if(flags & 1)
{
sx = x1 + (y2 - y1);
sy = y1 - (x2 - x1);
}
else
{
while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
{
sx = (lp.x1 + sx) >> 1;
sy = (lp.y1 + sy) >> 1;
}
}
if(flags & 2)
{
ex = x2 + (y2 - y1);
ey = y2 - (x2 - x1);
}
else
{
while(abs(ex - lp.x2) + abs(ey - lp.y2) > lp2.len)
{
ex = (lp.x2 + ex) >> 1;
ey = (lp.y2 + ey) >> 1;
}
}
line3_no_clip(lp2, sx, sy, ex, ey);
}
else
{
line3_no_clip(lp, sx, sy, ex, ey);
}
}
}
else
{
while(li.step_hor());
line3_no_clip(lp, sx, sy, ex, ey);
}
}
private:
base_ren_type* m_ren;
base_ren_type* m_ren;
const line_profile_aa* m_profile;
color_type m_color;
color_type m_color;
rect_i m_clip_box;
bool m_clipping;
};
+154 -62
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -15,10 +15,12 @@
#ifndef AGG_RENDERER_OUTLINE_IMAGE_INCLUDED
#define AGG_RENDERER_OUTLINE_IMAGE_INCLUDED
#include <math.h>
#include "agg_array.h"
#include "agg_math.h"
#include "agg_line_aa_basics.h"
#include "agg_dda_line.h"
#include "agg_rendering_buffer.h"
#include "agg_clip_liang_barsky.h"
namespace agg
@@ -41,13 +43,12 @@ namespace agg
color_type pixel(int x, int y) const
{
//double src_y = (y + 0.5) * m_scale - 0.5;
double src_y = y * m_scale;
int h = int(m_source.height()) - 1;
int y1 = int(floor(src_y));
double src_y = (y + 0.5) * m_scale - 0.5;
int h = m_source.height() - 1;
int y1 = ufloor(src_y);
int y2 = y1 + 1;
color_type pix1 = (y1 < 0) ? m_source.pixel(x, 0).transparent() : m_source.pixel(x, y1);
color_type pix2 = (y2 > h) ? m_source.pixel(x, h).transparent() : m_source.pixel(x, y2);
color_type pix1 = (y1 < 0) ? color_type::no_color() : m_source.pixel(x, y1);
color_type pix2 = (y2 > h) ? color_type::no_color() : m_source.pixel(x, y2);
return pix1.gradient(pix2, src_y - y1);
}
@@ -69,18 +70,12 @@ namespace agg
typedef Filter filter_type;
typedef typename filter_type::color_type color_type;
//--------------------------------------------------------------------
~line_image_pattern()
{
delete [] m_data;
}
//--------------------------------------------------------------------
line_image_pattern(const Filter& filter) :
m_filter(&filter),
m_dilation(filter.dilation() + 1),
m_dilation_hr(m_dilation << line_subpixel_shift),
m_data(0),
m_data(),
m_width(0),
m_height(0),
m_width_hr(0),
@@ -96,7 +91,7 @@ namespace agg
m_filter(&filter),
m_dilation(filter.dilation() + 1),
m_dilation_hr(m_dilation << line_subpixel_shift),
m_data(0),
m_data(),
m_width(0),
m_height(0),
m_width_hr(0),
@@ -110,25 +105,24 @@ namespace agg
//--------------------------------------------------------------------
template<class Source> void create(const Source& src)
{
m_height = unsigned(ceil((double)src.height()));
m_width = unsigned(ceil((double)src.width()));
m_width_hr = int(src.width() * line_subpixel_size);
m_half_height_hr = int(src.height() * line_subpixel_size/2);
m_offset_y_hr = m_dilation_hr + m_half_height_hr - line_subpixel_size/2;
m_half_height_hr += line_subpixel_size/2;
m_height = uceil(src.height());
m_width = uceil(src.width());
m_width_hr = uround(src.width() * line_subpixel_scale);
m_half_height_hr = uround(src.height() * line_subpixel_scale/2);
m_offset_y_hr = m_dilation_hr + m_half_height_hr - line_subpixel_scale/2;
m_half_height_hr += line_subpixel_scale/2;
delete [] m_data;
m_data = new color_type [(m_width + m_dilation * 2) * (m_height + m_dilation * 2)];
m_data.resize((m_width + m_dilation * 2) * (m_height + m_dilation * 2));
m_buf.attach(m_data, m_width + m_dilation * 2,
m_height + m_dilation * 2,
m_width + m_dilation * 2);
m_buf.attach(&m_data[0], m_width + m_dilation * 2,
m_height + m_dilation * 2,
m_width + m_dilation * 2);
unsigned x, y;
color_type* d1;
color_type* d2;
for(y = 0; y < m_height; y++)
{
d1 = m_buf.row(y + m_dilation) + m_dilation;
d1 = m_buf.row_ptr(y + m_dilation) + m_dilation;
for(x = 0; x < m_width; x++)
{
*d1++ = src.pixel(x, y);
@@ -139,24 +133,26 @@ namespace agg
const color_type* s2;
for(y = 0; y < m_dilation; y++)
{
s1 = m_buf.row(m_height + m_dilation - 1) + m_dilation;
s2 = m_buf.row(m_dilation) + m_dilation;
d1 = m_buf.row(m_dilation + m_height + y) + m_dilation;
d2 = m_buf.row(m_dilation - y - 1) + m_dilation;
//s1 = m_buf.row_ptr(m_height + m_dilation - 1) + m_dilation;
//s2 = m_buf.row_ptr(m_dilation) + m_dilation;
d1 = m_buf.row_ptr(m_dilation + m_height + y) + m_dilation;
d2 = m_buf.row_ptr(m_dilation - y - 1) + m_dilation;
for(x = 0; x < m_width; x++)
{
*d1++ = color_type(*s1++, 0);
*d2++ = color_type(*s2++, 0);
//*d1++ = color_type(*s1++, 0);
//*d2++ = color_type(*s2++, 0);
*d1++ = color_type::no_color();
*d2++ = color_type::no_color();
}
}
unsigned h = m_height + m_dilation * 2;
for(y = 0; y < h; y++)
{
s1 = m_buf.row(y) + m_dilation;
s2 = m_buf.row(y) + m_dilation + m_width;
d1 = m_buf.row(y) + m_dilation + m_width;
d2 = m_buf.row(y) + m_dilation;
s1 = m_buf.row_ptr(y) + m_dilation;
s2 = m_buf.row_ptr(y) + m_dilation + m_width;
d1 = m_buf.row_ptr(y) + m_dilation + m_width;
d2 = m_buf.row_ptr(y) + m_dilation;
for(x = 0; x < m_dilation; x++)
{
@@ -169,6 +165,7 @@ namespace agg
//--------------------------------------------------------------------
int pattern_width() const { return m_width_hr; }
int line_width() const { return m_half_height_hr; }
double width() const { return m_height; }
//--------------------------------------------------------------------
void pixel(color_type* p, int x, int y) const
@@ -192,7 +189,7 @@ namespace agg
const filter_type* m_filter;
unsigned m_dilation;
int m_dilation_hr;
color_type* m_data;
pod_array<color_type> m_data;
unsigned m_width;
unsigned m_height;
int m_width_hr;
@@ -276,23 +273,23 @@ namespace agg
m_dx_end(line_mr(ex) - line_mr(x2)),
m_dy_end(line_mr(ey) - line_mr(y2)),
m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
double(y + line_subpixel_size/2 - y2) * double(m_dx))),
m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
double(y + line_subpixel_scale/2 - y2) * double(m_dx))),
m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start -
(line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start),
m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start -
(line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start),
m_dist_end((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_end -
(line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_end),
m_len(int(len / scale))
m_dist_end((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_end -
(line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_end),
m_len(uround(len / scale))
{
double d = len * scale;
int dx = int(((x2 - x1) << line_subpixel_shift) / d);
int dy = int(((y2 - y1) << line_subpixel_shift) / d);
int dx = iround(((x2 - x1) << line_subpixel_shift) / d);
int dy = iround(((y2 - y1) << line_subpixel_shift) / d);
m_dx_pict = -dy;
m_dy_pict = dx;
m_dist_pict = ((x + line_subpixel_size/2 - (x1 - dy)) * m_dy_pict -
(y + line_subpixel_size/2 - (y1 + dx)) * m_dx_pict) >>
m_dist_pict = ((x + line_subpixel_scale/2 - (x1 - dy)) * m_dy_pict -
(y + line_subpixel_scale/2 - (y1 + dx)) * m_dx_pict) >>
line_subpixel_shift;
m_dx <<= line_subpixel_shift;
@@ -478,7 +475,7 @@ namespace agg
typedef typename Renderer::color_type color_type;
//---------------------------------------------------------------------
enum
enum max_half_width_e
{
max_half_width = 64
};
@@ -503,7 +500,8 @@ namespace agg
m_count((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
abs((lp.x2 >> line_subpixel_shift) - m_x))),
m_width(ren.subpixel_width()),
m_max_extent(m_width >> (line_subpixel_shift - 2)),
//m_max_extent(m_width >> (line_subpixel_shift - 2)),
m_max_extent((m_width + line_subpixel_scale) >> line_subpixel_shift),
m_start(pattern_start + (m_max_extent + 2) * ren.pattern_width()),
m_step(0)
{
@@ -513,7 +511,7 @@ namespace agg
lp.len);
unsigned i;
int stop = m_width + line_subpixel_size * 2;
int stop = m_width + line_subpixel_scale * 2;
for(i = 0; i < max_half_width; ++i)
{
m_dist_pos[i] = li.y();
@@ -822,25 +820,39 @@ namespace agg
m_ren(&ren),
m_pattern(&patt),
m_start(0),
m_scale_x(1.0)
{
}
m_scale_x(1.0),
m_clip_box(0,0,0,0),
m_clipping(false)
{}
void attach(base_ren_type& ren) { m_ren = &ren; }
//---------------------------------------------------------------------
void pattern(const pattern_type& p) { m_pattern = &p; }
const pattern_type& pattern() const { return *m_pattern; }
//---------------------------------------------------------------------
void reset_clipping() { m_clipping = false; }
void clip_box(double x1, double y1, double x2, double y2)
{
m_clip_box.x1 = line_coord_sat::conv(x1);
m_clip_box.y1 = line_coord_sat::conv(y1);
m_clip_box.x2 = line_coord_sat::conv(x2);
m_clip_box.y2 = line_coord_sat::conv(y2);
m_clipping = true;
}
//---------------------------------------------------------------------
void scale_x(double s) { m_scale_x = s; }
double scale_x() const { return m_scale_x; }
//---------------------------------------------------------------------
void start_x(double s) { m_start = int(s * line_subpixel_size); }
double start_x() const { return double(m_start) / line_subpixel_size; }
void start_x(double s) { m_start = iround(s * line_subpixel_scale); }
double start_x() const { return double(m_start) / line_subpixel_scale; }
//---------------------------------------------------------------------
int subpixel_width() const { return m_pattern->line_width(); }
int pattern_width() const { return m_pattern->pattern_width(); }
double width() const { return double(subpixel_width()) / line_subpixel_scale; }
//-------------------------------------------------------------------------
void pixel(color_type* p, int x, int y) const
@@ -869,6 +881,11 @@ namespace agg
{
}
//-------------------------------------------------------------------------
void pie(int, int, int, int, int, int)
{
}
//-------------------------------------------------------------------------
void line0(const line_parameters&)
{
@@ -885,9 +902,22 @@ namespace agg
}
//-------------------------------------------------------------------------
void line3(const line_parameters& lp,
int sx, int sy, int ex, int ey)
void line3_no_clip(const line_parameters& lp,
int sx, int sy, int ex, int ey)
{
if(lp.len > line_max_length)
{
line_parameters lp1, lp2;
lp.divide(lp1, lp2);
int mx = lp1.x2 + (lp1.y2 - lp1.y1);
int my = lp1.y2 - (lp1.x2 - lp1.x1);
line3_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my);
line3_no_clip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1);
return;
}
fix_degenerate_bisectrix_start(lp, &sx, &sy);
fix_degenerate_bisectrix_end(lp, &ex, &ey);
line_interpolator_image<self_type> li(*this, lp,
sx, sy,
ex, ey,
@@ -900,7 +930,67 @@ namespace agg
{
while(li.step_hor());
}
m_start = li.pattern_end();
m_start += uround(lp.len / m_scale_x);
}
//-------------------------------------------------------------------------
void line3(const line_parameters& lp,
int sx, int sy, int ex, int ey)
{
if(m_clipping)
{
int x1 = lp.x1;
int y1 = lp.y1;
int x2 = lp.x2;
int y2 = lp.y2;
unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
int start = m_start;
if((flags & 4) == 0)
{
if(flags)
{
line_parameters lp2(x1, y1, x2, y2,
uround(calc_distance(x1, y1, x2, y2)));
if(flags & 1)
{
m_start += uround(calc_distance(lp.x1, lp.y1, x1, y1) / m_scale_x);
sx = x1 + (y2 - y1);
sy = y1 - (x2 - x1);
}
else
{
while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
{
sx = (lp.x1 + sx) >> 1;
sy = (lp.y1 + sy) >> 1;
}
}
if(flags & 2)
{
ex = x2 + (y2 - y1);
ey = y2 - (x2 - x1);
}
else
{
while(abs(ex - lp.x2) + abs(ey - lp.y2) > lp2.len)
{
ex = (lp.x2 + ex) >> 1;
ey = (lp.y2 + ey) >> 1;
}
}
line3_no_clip(lp2, sx, sy, ex, ey);
}
else
{
line3_no_clip(lp, sx, sy, ex, ey);
}
}
m_start = start + uround(lp.len / m_scale_x);
}
else
{
line3_no_clip(lp, sx, sy, ex, ey);
}
}
private:
@@ -908,6 +998,8 @@ namespace agg
const pattern_type* m_pattern;
int m_start;
double m_scale_x;
rect_i m_clip_box;
bool m_clipping;
};
+5 -5
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -41,13 +41,13 @@ namespace agg
m_line_color(),
m_curr_x(0),
m_curr_y(0)
{
}
{}
void attach(base_ren_type& ren) { m_ren = &ren; }
//--------------------------------------------------------------------
static int coord(double c)
{
return int(c * line_bresenham_interpolator::subpixel_size);
return iround(c * line_bresenham_interpolator::subpixel_scale);
}
//--------------------------------------------------------------------
+5 -5
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -34,8 +34,8 @@ namespace agg
renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph) :
m_ren(&ren),
m_glyph(&glyph)
{
}
{}
void attach(ren_type& ren) { m_ren = &ren; }
//--------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
@@ -219,7 +219,7 @@ namespace agg
m_glyph->prepare(&r, x, y, *str, flip);
if(r.x2 >= r.x1)
{
m_ren->prepare(r.x2 - r.x1 + 1);
m_ren->prepare();
int i;
if(flip)
{
+551 -171
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -18,96 +18,89 @@
#include "agg_basics.h"
#include "agg_renderer_base.h"
#include "agg_render_scanlines.h"
namespace agg
{
//====================================================renderer_scanline_aa
template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa
//================================================render_scanline_aa_solid
template<class Scanline, class BaseRenderer, class ColorT>
void render_scanline_aa_solid(const Scanline& sl,
BaseRenderer& ren,
const ColorT& color)
{
public:
typedef BaseRenderer base_ren_type;
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
//--------------------------------------------------------------------
renderer_scanline_aa(base_ren_type& ren, SpanGenerator& span_gen) :
m_ren(&ren),
m_span_gen(&span_gen)
for(;;)
{
}
//--------------------------------------------------------------------
void prepare(unsigned max_span_len)
{
m_span_gen->prepare(max_span_len);
}
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
int y = sl.y();
m_ren->first_clip_box();
do
int x = span->x;
if(span->len > 0)
{
int xmin = m_ren->xmin();
int xmax = m_ren->xmax();
ren.blend_solid_hspan(x, y, (unsigned)span->len,
color,
span->covers);
}
else
{
ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
color,
*(span->covers));
}
if(--num_spans == 0) break;
++span;
}
}
if(y >= m_ren->ymin() && y <= m_ren->ymax())
//===============================================render_scanlines_aa_solid
template<class Rasterizer, class Scanline,
class BaseRenderer, class ColorT>
void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl,
BaseRenderer& ren, const ColorT& color)
{
if(ras.rewind_scanlines())
{
// Explicitly convert "color" to the BaseRenderer color type.
// For example, it can be called with color type "rgba", while
// "rgba8" is needed. Otherwise it will be implicitly
// converted in the loop many times.
//----------------------
typename BaseRenderer::color_type ren_color(color);
sl.reset(ras.min_x(), ras.max_x());
while(ras.sweep_scanline(sl))
{
//render_scanline_aa_solid(sl, ren, ren_color);
// This code is equivalent to the above call (copy/paste).
// It's just a "manual" optimization for old compilers,
// like Microsoft Visual C++ v6.0
//-------------------------------
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
do
int x = span->x;
if(span->len > 0)
{
int x = span->x;
int len = span->len;
bool solid = false;
const typename Scanline::cover_type* covers = span->covers;
if(len < 0)
{
solid = true;
len = -len;
}
if(x < xmin)
{
len -= xmin - x;
if(!solid)
{
covers += xmin - x;
}
x = xmin;
}
if(len > 0)
{
if(x + len > xmax)
{
len = xmax - x + 1;
}
if(len > 0)
{
m_ren->blend_color_hspan_no_clip(
x, y, len,
m_span_gen->generate(x, y, len),
solid ? 0 : covers,
*covers);
}
}
++span;
ren.blend_solid_hspan(x, y, (unsigned)span->len,
ren_color,
span->covers);
}
while(--num_spans);
else
{
ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
ren_color,
*(span->covers));
}
if(--num_spans == 0) break;
++span;
}
}
while(m_ren->next_clip_box());
}
private:
base_ren_type* m_ren;
SpanGenerator* m_span_gen;
};
}
//==============================================renderer_scanline_aa_solid
template<class BaseRenderer> class renderer_scanline_aa_solid
@@ -117,9 +110,11 @@ namespace agg
typedef typename base_ren_type::color_type color_type;
//--------------------------------------------------------------------
renderer_scanline_aa_solid(base_ren_type& ren) :
m_ren(&ren)
renderer_scanline_aa_solid() : m_ren(0) {}
renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) {}
void attach(base_ren_type& ren)
{
m_ren = &ren;
}
//--------------------------------------------------------------------
@@ -127,33 +122,12 @@ namespace agg
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
void prepare(unsigned) {}
void prepare() {}
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
do
{
int x = span->x;
if(span->len > 0)
{
m_ren->blend_solid_hspan(x, y, (unsigned)span->len,
m_color,
span->covers);
}
else
{
m_ren->blend_hline(x, y, (unsigned)(x - span->len - 1),
m_color,
*(span->covers));
}
++span;
}
while(--num_spans);
render_scanline_aa_solid(sl, *m_ren, m_color);
}
private:
@@ -167,79 +141,167 @@ namespace agg
//===================================================renderer_scanline_bin
template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin
//======================================================render_scanline_aa
template<class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanline_aa(const Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
int x = span->x;
int len = span->len;
const typename Scanline::cover_type* covers = span->covers;
if(len < 0) len = -len;
typename BaseRenderer::color_type* colors = alloc.allocate(len);
span_gen.generate(colors, x, y, len);
ren.blend_color_hspan(x, y, len, colors,
(span->len < 0) ? 0 : covers, *covers);
if(--num_spans == 0) break;
++span;
}
}
//=====================================================render_scanlines_aa
template<class Rasterizer, class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
if(ras.rewind_scanlines())
{
sl.reset(ras.min_x(), ras.max_x());
span_gen.prepare();
while(ras.sweep_scanline(sl))
{
render_scanline_aa(sl, ren, alloc, span_gen);
}
}
}
//====================================================renderer_scanline_aa
template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
class renderer_scanline_aa
{
public:
typedef BaseRenderer base_ren_type;
typedef BaseRenderer base_ren_type;
typedef SpanAllocator alloc_type;
typedef SpanGenerator span_gen_type;
//--------------------------------------------------------------------
renderer_scanline_bin(base_ren_type& ren, SpanGenerator& span_gen) :
renderer_scanline_aa() : m_ren(0), m_alloc(0), m_span_gen(0) {}
renderer_scanline_aa(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen) :
m_ren(&ren),
m_alloc(&alloc),
m_span_gen(&span_gen)
{}
void attach(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen)
{
m_ren = &ren;
m_alloc = &alloc;
m_span_gen = &span_gen;
}
//--------------------------------------------------------------------
void prepare(unsigned max_span_len)
{
m_span_gen->prepare(max_span_len);
}
void prepare() { m_span_gen->prepare(); }
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
int y = sl.y();
m_ren->first_clip_box();
do
{
int xmin = m_ren->xmin();
int xmax = m_ren->xmax();
if(y >= m_ren->ymin() && y <= m_ren->ymax())
{
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
do
{
int x = span->x;
int len = span->len;
if(len < 0) len = -len;
if(x < xmin)
{
len -= xmin - x;
x = xmin;
}
if(len > 0)
{
if(x + len > xmax)
{
len = xmax - x + 1;
}
if(len > 0)
{
m_ren->blend_color_hspan_no_clip(
x, y, len,
m_span_gen->generate(x, y, len),
0);
}
}
++span;
}
while(--num_spans);
}
}
while(m_ren->next_clip_box());
render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen);
}
private:
base_ren_type* m_ren;
SpanGenerator* m_span_gen;
alloc_type* m_alloc;
span_gen_type* m_span_gen;
};
//===============================================render_scanline_bin_solid
template<class Scanline, class BaseRenderer, class ColorT>
void render_scanline_bin_solid(const Scanline& sl,
BaseRenderer& ren,
const ColorT& color)
{
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
ren.blend_hline(span->x,
sl.y(),
span->x - 1 + ((span->len < 0) ?
-span->len :
span->len),
color,
cover_full);
if(--num_spans == 0) break;
++span;
}
}
//==============================================render_scanlines_bin_solid
template<class Rasterizer, class Scanline,
class BaseRenderer, class ColorT>
void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl,
BaseRenderer& ren, const ColorT& color)
{
if(ras.rewind_scanlines())
{
// Explicitly convert "color" to the BaseRenderer color type.
// For example, it can be called with color type "rgba", while
// "rgba8" is needed. Otherwise it will be implicitly
// converted in the loop many times.
//----------------------
typename BaseRenderer::color_type ren_color(color);
sl.reset(ras.min_x(), ras.max_x());
while(ras.sweep_scanline(sl))
{
//render_scanline_bin_solid(sl, ren, ren_color);
// This code is equivalent to the above call (copy/paste).
// It's just a "manual" optimization for old compilers,
// like Microsoft Visual C++ v6.0
//-------------------------------
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
ren.blend_hline(span->x,
sl.y(),
span->x - 1 + ((span->len < 0) ?
-span->len :
span->len),
ren_color,
cover_full);
if(--num_spans == 0) break;
++span;
}
}
}
}
//=============================================renderer_scanline_bin_solid
template<class BaseRenderer> class renderer_scanline_bin_solid
{
@@ -248,9 +310,11 @@ namespace agg
typedef typename base_ren_type::color_type color_type;
//--------------------------------------------------------------------
renderer_scanline_bin_solid(base_ren_type& ren) :
m_ren(&ren)
renderer_scanline_bin_solid() : m_ren(0) {}
renderer_scanline_bin_solid(base_ren_type& ren) : m_ren(&ren) {}
void attach(base_ren_type& ren)
{
m_ren = &ren;
}
//--------------------------------------------------------------------
@@ -258,25 +322,12 @@ namespace agg
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
void prepare(unsigned) {}
void prepare() {}
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
do
{
m_ren->blend_hline(span->x,
sl.y(),
span->x - 1 + ((span->len < 0) ?
-span->len :
span->len),
m_color,
cover_full);
++span;
}
while(--num_spans);
render_scanline_bin_solid(sl, *m_ren, m_color);
}
private:
@@ -284,6 +335,335 @@ namespace agg
color_type m_color;
};
//======================================================render_scanline_bin
template<class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanline_bin(const Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
int x = span->x;
int len = span->len;
if(len < 0) len = -len;
typename BaseRenderer::color_type* colors = alloc.allocate(len);
span_gen.generate(colors, x, y, len);
ren.blend_color_hspan(x, y, len, colors, 0, cover_full);
if(--num_spans == 0) break;
++span;
}
}
//=====================================================render_scanlines_bin
template<class Rasterizer, class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
if(ras.rewind_scanlines())
{
sl.reset(ras.min_x(), ras.max_x());
span_gen.prepare();
while(ras.sweep_scanline(sl))
{
render_scanline_bin(sl, ren, alloc, span_gen);
}
}
}
//====================================================renderer_scanline_bin
template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
class renderer_scanline_bin
{
public:
typedef BaseRenderer base_ren_type;
typedef SpanAllocator alloc_type;
typedef SpanGenerator span_gen_type;
//--------------------------------------------------------------------
renderer_scanline_bin() : m_ren(0), m_alloc(0), m_span_gen(0) {}
renderer_scanline_bin(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen) :
m_ren(&ren),
m_alloc(&alloc),
m_span_gen(&span_gen)
{}
void attach(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen)
{
m_ren = &ren;
m_alloc = &alloc;
m_span_gen = &span_gen;
}
//--------------------------------------------------------------------
void prepare() { m_span_gen->prepare(); }
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen);
}
private:
base_ren_type* m_ren;
alloc_type* m_alloc;
span_gen_type* m_span_gen;
};
//========================================================render_scanlines
template<class Rasterizer, class Scanline, class Renderer>
void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren)
{
if(ras.rewind_scanlines())
{
sl.reset(ras.min_x(), ras.max_x());
ren.prepare();
while(ras.sweep_scanline(sl))
{
ren.render(sl);
}
}
}
//========================================================render_all_paths
template<class Rasterizer, class Scanline, class Renderer,
class VertexSource, class ColorStorage, class PathId>
void render_all_paths(Rasterizer& ras,
Scanline& sl,
Renderer& r,
VertexSource& vs,
const ColorStorage& as,
const PathId& path_id,
unsigned num_paths)
{
for(unsigned i = 0; i < num_paths; i++)
{
ras.reset();
ras.add_path(vs, path_id[i]);
r.color(as[i]);
render_scanlines(ras, sl, r);
}
}
//=============================================render_scanlines_compound
template<class Rasterizer,
class ScanlineAA,
class ScanlineBin,
class BaseRenderer,
class SpanAllocator,
class StyleHandler>
void render_scanlines_compound(Rasterizer& ras,
ScanlineAA& sl_aa,
ScanlineBin& sl_bin,
BaseRenderer& ren,
SpanAllocator& alloc,
StyleHandler& sh)
{
if(ras.rewind_scanlines())
{
int min_x = ras.min_x();
int len = ras.max_x() - min_x + 2;
sl_aa.reset(min_x, ras.max_x());
typedef typename BaseRenderer::color_type color_type;
color_type* color_span = alloc.allocate(len * 2);
color_type* mix_buffer = color_span + len;
cover_type* cover_buffer = ras.allocate_cover_buffer(len);
unsigned num_spans;
unsigned num_styles;
unsigned style;
bool solid;
while((num_styles = ras.sweep_styles()) > 0)
{
typename ScanlineAA::const_iterator span_aa;
if(num_styles == 1)
{
// Optimization for a single style. Happens often
//-------------------------
if(ras.sweep_scanline(sl_aa, 0))
{
style = ras.style(0);
if(sh.is_solid(style))
{
// Just solid fill
//-----------------------
render_scanline_aa_solid(sl_aa, ren, sh.color(style));
}
else
{
// Arbitrary span generator
//-----------------------
span_aa = sl_aa.begin();
num_spans = sl_aa.num_spans();
for(;;)
{
len = span_aa->len;
sh.generate_span(color_span,
span_aa->x,
sl_aa.y(),
len,
style);
ren.blend_color_hspan(span_aa->x,
sl_aa.y(),
span_aa->len,
color_span,
span_aa->covers);
if(--num_spans == 0) break;
++span_aa;
}
}
}
}
else
{
int sl_start = ras.scanline_start();
unsigned sl_len = ras.scanline_length();
if(sl_len)
{
memset(mix_buffer + sl_start - min_x,
0,
sl_len * sizeof(color_type));
memset(cover_buffer + sl_start - min_x,
0,
sl_len * sizeof(cover_type));
int sl_y = 0x7FFFFFFF;
unsigned i;
for(i = 0; i < num_styles; i++)
{
style = ras.style(i);
solid = sh.is_solid(style);
if(ras.sweep_scanline(sl_aa, i))
{
unsigned cover;
color_type* colors;
color_type* cspan;
cover_type* src_covers;
cover_type* dst_covers;
span_aa = sl_aa.begin();
num_spans = sl_aa.num_spans();
sl_y = sl_aa.y();
if(solid)
{
// Just solid fill
//-----------------------
for(;;)
{
color_type c = sh.color(style);
len = span_aa->len;
colors = mix_buffer + span_aa->x - min_x;
src_covers = span_aa->covers;
dst_covers = cover_buffer + span_aa->x - min_x;
do
{
cover = *src_covers;
if(*dst_covers + cover > cover_full)
{
cover = cover_full - *dst_covers;
}
if(cover)
{
colors->add(c, cover);
*dst_covers += cover;
}
++colors;
++src_covers;
++dst_covers;
}
while(--len);
if(--num_spans == 0) break;
++span_aa;
}
}
else
{
// Arbitrary span generator
//-----------------------
for(;;)
{
len = span_aa->len;
colors = mix_buffer + span_aa->x - min_x;
cspan = color_span;
sh.generate_span(cspan,
span_aa->x,
sl_aa.y(),
len,
style);
src_covers = span_aa->covers;
dst_covers = cover_buffer + span_aa->x - min_x;
do
{
cover = *src_covers;
if(*dst_covers + cover > cover_full)
{
cover = cover_full - *dst_covers;
}
if(cover)
{
colors->add(*cspan, cover);
*dst_covers += cover;
}
++cspan;
++colors;
++src_covers;
++dst_covers;
}
while(--len);
if(--num_spans == 0) break;
++span_aa;
}
}
}
}
ren.blend_color_hspan(sl_start,
sl_y,
sl_len,
mix_buffer + sl_start - min_x,
0,
cover_full);
} //if(sl_len)
} //if(num_styles == 1) ... else
} //while((num_styles = ras.sweep_styles()) > 0)
} //if(ras.rewind_scanlines())
}
}
#endif
+34 -44
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -20,7 +20,7 @@
#ifndef AGG_RENDERING_BUFFER_INCLUDED
#define AGG_RENDERING_BUFFER_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
namespace agg
{
@@ -39,31 +39,23 @@ namespace agg
x1(x1_), x2(x2_), ptr(ptr_) {}
};
//-------------------------------------------------------------------
~row_ptr_cache()
{
delete [] m_rows;
}
//-------------------------------------------------------------------
row_ptr_cache() :
m_buf(0),
m_rows(0),
m_rows(),
m_width(0),
m_height(0),
m_stride(0),
m_max_height(0)
m_stride(0)
{
}
//--------------------------------------------------------------------
row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) :
m_buf(0),
m_rows(0),
m_rows(),
m_width(0),
m_height(0),
m_stride(0),
m_max_height(0)
m_stride(0)
{
attach(buf, width, height, stride);
}
@@ -75,10 +67,9 @@ namespace agg
m_width = width;
m_height = height;
m_stride = stride;
if(height > m_max_height)
if(height > m_rows.size())
{
delete [] m_rows;
m_rows = new T* [m_max_height = height];
m_rows.resize(height);
}
T* row_ptr = m_buf;
@@ -88,7 +79,7 @@ namespace agg
row_ptr = m_buf - int(height - 1) * stride;
}
T** rows = m_rows;
T** rows = &m_rows[0];
while(height--)
{
@@ -98,37 +89,42 @@ namespace agg
}
//--------------------------------------------------------------------
T* buf() { return m_buf; }
const T* buf() const { return m_buf; }
unsigned width() const { return m_width; }
unsigned height() const { return m_height; }
int stride() const { return m_stride; }
unsigned stride_abs() const
{
return (m_stride < 0) ?
unsigned(-m_stride) :
unsigned(m_stride);
return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
}
//--------------------------------------------------------------------
T* row(unsigned y) { return m_rows[y]; }
const T* row(unsigned y) const { return m_rows[y]; }
T const* const* rows() const { return m_rows; }
T* row_ptr(int, int y, unsigned) { return m_rows[y]; }
T* row_ptr(int y) { return m_rows[y]; }
const T* row_ptr(int y) const { return m_rows[y]; }
row_data row (int y) const { return row_data(0, m_width-1, m_rows[y]); }
//--------------------------------------------------------------------
void copy_from(const row_ptr_cache<T>& mtx)
T const* const* rows() const { return &m_rows[0]; }
//--------------------------------------------------------------------
template<class RenBuf>
void copy_from(const RenBuf& src)
{
unsigned h = height();
if(mtx.height() < h) h = mtx.height();
if(src.height() < h) h = src.height();
unsigned l = stride_abs();
if(mtx.stride_abs() < l) l = mtx.stride_abs();
if(src.stride_abs() < l) l = src.stride_abs();
l *= sizeof(T);
unsigned y;
unsigned w = width();
for (y = 0; y < h; y++)
{
memcpy(row(y), mtx.row(y), l);
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
}
}
@@ -136,32 +132,26 @@ namespace agg
void clear(T value)
{
unsigned y;
unsigned w = width();
unsigned stride = stride_abs();
for(y = 0; y < height(); y++)
{
T* p = row(y);
T* p = row_ptr(0, y, w);
unsigned x;
for(x = 0; x < stride_abs(); x++)
for(x = 0; x < stride; x++)
{
*p++ = value;
}
}
}
private:
//--------------------------------------------------------------------
// Prohibit copying
row_ptr_cache(const row_ptr_cache<T>&);
const row_ptr_cache<T>& operator = (const row_ptr_cache<T>&);
private:
//--------------------------------------------------------------------
T* m_buf; // Pointer to renrdering buffer
T** m_rows; // Pointers to each row of the buffer
unsigned m_width; // Width in pixels
unsigned m_height; // Height in pixels
int m_stride; // Number of bytes per row. Can be < 0
unsigned m_max_height; // The maximal height (currently allocated)
T* m_buf; // Pointer to renrdering buffer
pod_array<T*> m_rows; // Pointers to each row of the buffer
unsigned m_width; // Width in pixels
unsigned m_height; // Height in pixels
int m_stride; // Number of bytes per row. Can be < 0
};
+45 -87
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -20,7 +20,7 @@
#ifndef AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
#define AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
namespace agg
{
@@ -32,110 +32,73 @@ namespace agg
// Generally it's more efficient to use this class as a temporary buffer
// for rendering a few lines and then to blend it with another buffer.
//
template<unsigned PixWidth> class rendering_buffer_dynarow
class rendering_buffer_dynarow
{
public:
//-------------------------------------------------------------------
//----------------------------------------------------------------------
struct row_data
{
int8u* ptr;
int x1;
int x2;
int x1, x2;
const int8u* ptr;
};
//-------------------------------------------------------------------
~rendering_buffer_dynarow()
{
init(0,0);
init(0,0,0);
}
//-------------------------------------------------------------------
rendering_buffer_dynarow() :
m_rows(0),
m_rows(),
m_width(0),
m_height(0)
m_height(0),
m_byte_width(0)
{
}
// Allocate and clear the buffer
//--------------------------------------------------------------------
rendering_buffer_dynarow(unsigned width, unsigned height) :
m_rows(new row_data[height]),
rendering_buffer_dynarow(unsigned width, unsigned height,
unsigned byte_width) :
m_rows(height),
m_width(width),
m_height(height)
m_height(height),
m_byte_width(byte_width)
{
memset(m_rows, 0, sizeof(row_data) * height);
memset(&m_rows[0], 0, sizeof(row_data) * height);
}
// Allocate and clear the buffer
//--------------------------------------------------------------------
void init(unsigned width, unsigned height)
void init(unsigned width, unsigned height, unsigned byte_width)
{
unsigned i;
for(i = 0; i < m_height; ++i) delete [] m_rows[i].ptr;
delete [] m_rows;
m_rows = 0;
for(i = 0; i < m_height; ++i)
{
pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width);
}
if(width && height)
{
m_width = width;
m_height = height;
m_rows = new row_data[height];
memset(m_rows, 0, sizeof(row_data) * height);
m_byte_width = byte_width;
m_rows.resize(height);
memset(&m_rows[0], 0, sizeof(row_data) * height);
}
}
//--------------------------------------------------------------------
unsigned width() const { return m_width; }
unsigned height() const { return m_height; }
// Get pointer to the beginning of the row. Memory for the row
// is allocated as needed.
//--------------------------------------------------------------------
int8u* row(int y)
{
row_data* r = m_rows + y;
if(r->ptr == 0)
{
r->ptr = new int8u [m_width * PixWidth];
memset(r->ptr, 0, m_width * PixWidth);
}
return r->ptr;
}
// Get const pointer to the row. The caller must check it for null.
//--------------------------------------------------------------------
const int8u* row(int y) const
{
return m_rows[y].ptr;
}
// Get the Y-th span. The pointer r.ptr is automatically adjusted
// to the actual beginning of the span. Use this function as follows:
//
// rendering_buffer_dynarow::row_data r = rbuf.span(x, y);
// if(r.ptr)
// {
// do { blend(r.ptr); r.ptr += PixWidth } while(++r.x1 < r.x2);
// }
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
row_data r = m_rows[y];
if(r.ptr)
{
if(x < r.x1) x = r.x1;
r.ptr += x * PixWidth;
}
return r;
}
unsigned width() const { return m_width; }
unsigned height() const { return m_height; }
unsigned byte_width() const { return m_byte_width; }
// The main function used for rendering. Returns pointer to the
// pre-allocated span. Memory for the row is allocated as needed.
//--------------------------------------------------------------------
int8u* span_ptr(int x, int y, unsigned len)
int8u* row_ptr(int x, int y, unsigned len)
{
row_data* r = m_rows + y;
row_data* r = &m_rows[y];
int x2 = x + len - 1;
if(r->ptr)
{
@@ -144,37 +107,32 @@ namespace agg
}
else
{
r->ptr = new int8u [m_width * PixWidth];
r->x1 = x;
r->x2 = x2;
memset(r->ptr, 0, m_width * PixWidth);
int8u* p = pod_allocator<int8u>::allocate(m_byte_width);
r->ptr = p;
r->x1 = x;
r->x2 = x2;
memset(p, 0, m_byte_width);
}
return r->ptr + x * PixWidth;
return (int8u*)r->ptr;
}
// Get const pointer to the span. Used mostly in GetPixel function
// The caller must check the returned pointer for null.
//--------------------------------------------------------------------
const int8u* span_ptr(int x, int y, unsigned) const
{
row_data* r = m_rows + y;
return r->ptr ? r->ptr + x * PixWidth : 0;
}
const int8u* row_ptr(int y) const { return m_rows[y].ptr; }
int8u* row_ptr(int y) { return row_ptr(0, y, m_width); }
row_data row (int y) const { return m_rows[y]; }
private:
//--------------------------------------------------------------------
// Prohibit copying
rendering_buffer_dynarow(const rendering_buffer_dynarow<PixWidth>&);
const rendering_buffer_dynarow<PixWidth>&
operator = (const rendering_buffer_dynarow<PixWidth>&);
rendering_buffer_dynarow(const rendering_buffer_dynarow&);
const rendering_buffer_dynarow& operator = (const rendering_buffer_dynarow&);
private:
//--------------------------------------------------------------------
row_data* m_rows; // Pointers to each row of the buffer
unsigned m_width; // Width in pixels
unsigned m_height; // Height in pixels
pod_array<row_data> m_rows; // Pointers to each row of the buffer
unsigned m_width; // Width in pixels
unsigned m_height; // Height in pixels
unsigned m_byte_width; // Width in bytes
};
+2 -9
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -22,8 +22,6 @@
#include "agg_basics.h"
#include "agg_arc.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -51,11 +49,6 @@ namespace agg
void rewind(unsigned);
unsigned vertex(double* x, double* y);
typedef rounded_rect source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
double m_x1;
double m_y1;
+196 -103
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -16,10 +16,19 @@
// Class scanline_bin - binary scanline.
//
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates (scanline32_bin) has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_BIN_INCLUDED
#define AGG_SCANLINE_BIN_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
namespace agg
{
@@ -30,36 +39,12 @@ namespace agg
// used in the rasterizer::render(). See description of agg_scanline_u8
// for details.
//
// Rendering:
//-------------------------------------------------------------------------
//
// int y = sl.y();
//
// ************************************
// ...Perform vertical clipping here...
// ************************************
//
// unsigned num_spans = sl.num_spans();
// const agg::scanline_bin::span* cur_span = sl.spans();
//
// do
// {
// x = cur_span->x;
// len = cur_span->len;
//
// **************************************
// ...Perform horizontal clipping here...
// **************************************
//
// hor_line(x, y, len)
// ++cur_span;
// }
// while(--num_spans);
//
//------------------------------------------------------------------------
class scanline_bin
{
public:
typedef int32 coord_type;
struct span
{
int16 x;
@@ -68,103 +53,211 @@ namespace agg
typedef const span* const_iterator;
~scanline_bin()
{
delete [] m_spans;
}
//--------------------------------------------------------------------
scanline_bin() :
m_max_len(0),
m_last_x(0x7FFF),
m_spans(0),
m_last_x(0x7FFFFFF0),
m_spans(),
m_cur_span(0)
{
}
void reset(int min_x, int max_x);
void add_cell(int x, unsigned);
void add_cells(int x, unsigned len, const void*);
void add_span(int x, unsigned len, unsigned);
void finalize(int y) { m_y = y; }
void reset_spans();
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 3;
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned)
{
if(x == m_last_x+1)
{
m_cur_span->len++;
}
else
{
++m_cur_span;
m_cur_span->x = (int16)x;
m_cur_span->len = 1;
}
m_last_x = x;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned)
{
if(x == m_last_x+1)
{
m_cur_span->len = (int16)(m_cur_span->len + len);
}
else
{
++m_cur_span;
m_cur_span->x = (int16)x;
m_cur_span->len = (int16)len;
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const void*)
{
add_span(x, len, 0);
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - m_spans); }
const_iterator begin() const { return m_spans + 1; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
private:
scanline_bin(const scanline_bin&);
const scanline_bin operator = (const scanline_bin&);
unsigned m_max_len;
int m_last_x;
int m_y;
span* m_spans;
span* m_cur_span;
int m_last_x;
int m_y;
pod_array<span> m_spans;
span* m_cur_span;
};
//------------------------------------------------------------------------
inline void scanline_bin::reset(int min_x, int max_x)
//===========================================================scanline32_bin
class scanline32_bin
{
unsigned max_len = max_x - min_x + 3;
if(max_len > m_max_len)
public:
typedef int32 coord_type;
//--------------------------------------------------------------------
struct span
{
delete [] m_spans;
m_spans = new span [max_len];
m_max_len = max_len;
}
m_last_x = 0x7FFF;
m_cur_span = m_spans;
}
span() {}
span(coord_type x_, coord_type len_) : x(x_), len(len_) {}
coord_type x;
coord_type len;
};
typedef pod_bvector<span, 4> span_array_type;
//------------------------------------------------------------------------
inline void scanline_bin::reset_spans()
{
m_last_x = 0x7FFF;
m_cur_span = m_spans;
}
//------------------------------------------------------------------------
inline void scanline_bin::add_cell(int x, unsigned)
{
if(x == m_last_x+1)
//--------------------------------------------------------------------
class const_iterator
{
m_cur_span->len++;
}
else
{
++m_cur_span;
m_cur_span->x = (int16)x;
m_cur_span->len = 1;
}
m_last_x = x;
}
public:
const_iterator(const span_array_type& spans) :
m_spans(spans),
m_span_idx(0)
{}
const span& operator*() const { return m_spans[m_span_idx]; }
const span* operator->() const { return &m_spans[m_span_idx]; }
void operator ++ () { ++m_span_idx; }
private:
const span_array_type& m_spans;
unsigned m_span_idx;
};
//--------------------------------------------------------------------
scanline32_bin() : m_max_len(0), m_last_x(0x7FFFFFF0) {}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
m_last_x = 0x7FFFFFF0;
m_spans.remove_all();
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned)
{
if(x == m_last_x+1)
{
m_spans.last().len++;
}
else
{
m_spans.add(span(coord_type(x), 1));
}
m_last_x = x;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned)
{
if(x == m_last_x+1)
{
m_spans.last().len += coord_type(len);
}
else
{
m_spans.add(span(coord_type(x), coord_type(len)));
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const void*)
{
add_span(x, len, 0);
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_spans.remove_all();
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return m_spans.size(); }
const_iterator begin() const { return const_iterator(m_spans); }
private:
scanline32_bin(const scanline32_bin&);
const scanline32_bin operator = (const scanline32_bin&);
unsigned m_max_len;
int m_last_x;
int m_y;
span_array_type m_spans;
};
//------------------------------------------------------------------------
inline void scanline_bin::add_span(int x, unsigned len, unsigned)
{
if(x == m_last_x+1)
{
m_cur_span->len = (int16)(m_cur_span->len + len);
}
else
{
++m_cur_span;
m_cur_span->x = (int16)x;
m_cur_span->len = (int16)len;
}
m_last_x = x + len - 1;
}
//------------------------------------------------------------------------
inline void scanline_bin::add_cells(int x, unsigned len, const void*)
{
add_span(x, len, 0);
}
}
+108 -65
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -141,7 +141,7 @@ namespace agg
unsigned CoverShift = cover_shift>
struct sbool_intersect_spans_aa
{
enum
enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -253,7 +253,7 @@ namespace agg
unsigned CoverShift = cover_shift>
struct sbool_unite_spans_aa
{
enum
enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -358,23 +358,38 @@ namespace agg
};
//---------------------------------------------sbool_xor_formula_saddle
//---------------------------------------------sbool_xor_formula_linear
template<unsigned CoverShift = cover_shift>
struct sbool_xor_formula_saddle
struct sbool_xor_formula_linear
{
enum
enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
cover_mask = cover_size - 1
};
static unsigned calculate(unsigned a, unsigned b)
static AGG_INLINE unsigned calculate(unsigned a, unsigned b)
{
unsigned cover = a + b;
if(cover > cover_mask) cover = cover_mask + cover_mask - cover;
return cover;
}
};
//---------------------------------------------sbool_xor_formula_saddle
template<unsigned CoverShift = cover_shift>
struct sbool_xor_formula_saddle
{
enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
cover_mask = cover_size - 1
};
static AGG_INLINE unsigned calculate(unsigned a, unsigned b)
{
unsigned k = a * b;
if(k == cover_mask * cover_mask) return 0;
@@ -386,23 +401,12 @@ namespace agg
};
//--------------------------------------------sbool_xor_formula_linear
template<unsigned CoverShift = cover_shift>
struct sbool_xor_formula_linear
//-------------------------------------------sbool_xor_formula_abs_diff
struct sbool_xor_formula_abs_diff
{
enum
static AGG_INLINE unsigned calculate(unsigned a, unsigned b)
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
cover_mask = cover_size - 1
};
static unsigned calculate(unsigned a, unsigned b)
{
unsigned cover = a + b;
if(cover > cover_mask) cover = cover_mask + cover_mask - cover;
return cover;
return unsigned(abs(int(a) - int(b)));
}
};
@@ -420,7 +424,7 @@ namespace agg
unsigned CoverShift = cover_shift>
struct sbool_xor_spans_aa
{
enum
enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -509,7 +513,7 @@ namespace agg
unsigned CoverShift = cover_shift>
struct sbool_subtract_spans_aa
{
enum
enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -625,14 +629,14 @@ namespace agg
AddSpanFunctor add_span)
{
sl.reset_spans();
typename Scanline::const_iterator span = sl1.begin();
typename Scanline1::const_iterator span = sl1.begin();
unsigned num_spans = sl1.num_spans();
do
for(;;)
{
add_span(span, span->x, abs((int)span->len), sl);
if(--num_spans == 0) break;
++span;
}
while(--num_spans);
sl.finalize(sl1.y());
ren.render(sl);
}
@@ -667,8 +671,8 @@ namespace agg
unsigned num2 = sl2.num_spans();
if(num2 == 0) return;
typename Scanline::const_iterator span1 = sl1.begin();
typename Scanline::const_iterator span2 = sl2.begin();
typename Scanline1::const_iterator span1 = sl1.begin();
typename Scanline2::const_iterator span2 = sl2.begin();
while(num1 && num2)
{
@@ -701,20 +705,20 @@ namespace agg
{
--num1;
--num2;
++span1;
++span2;
if(num1) ++span1;
if(num2) ++span2;
}
else
{
if(advance_span1)
{
--num1;
++span1;
if(num1) ++span1;
}
else
{
--num2;
++span2;
if(num2) ++span2;
}
}
}
@@ -761,13 +765,13 @@ namespace agg
// Get the bounding boxes
//----------------
rect r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
rect r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y());
rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
rect_i r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y());
// Calculate the intersection of the bounding
// boxes and return if they don't intersect.
//-----------------
rect ir = intersect_rectangles(r1, r2);
rect_i ir = intersect_rectangles(r1, r2);
if(!ir.is_valid()) return;
// Reset the scanlines and get two first ones
@@ -778,7 +782,7 @@ namespace agg
if(!sg1.sweep_scanline(sl1)) return;
if(!sg2.sweep_scanline(sl2)) return;
ren.prepare(unsigned(ir.x2 - ir.x1 + 2));
ren.prepare();
// The main loop
// Here we synchronize the scanlines with
@@ -846,10 +850,14 @@ namespace agg
unsigned num1 = sl1.num_spans();
unsigned num2 = sl2.num_spans();
typename Scanline::const_iterator span1;
typename Scanline::const_iterator span2;
typename Scanline1::const_iterator span1;// = sl1.begin();
typename Scanline2::const_iterator span2;// = sl2.begin();
enum { invalid_b = 0x7FFFFFFF, invalid_e = invalid_b - 1 };
enum invalidation_e
{
invalid_b = 0xFFFFFFF,
invalid_e = invalid_b - 1
};
// Initialize the spans as invalid
//---------------
@@ -1033,15 +1041,19 @@ namespace agg
// Get the bounding boxes
//----------------
rect r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
rect r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y());
rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
rect_i r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y());
// Calculate the union of the bounding boxes
//-----------------
rect ur = unite_rectangles(r1, r2);
rect_i ur(1,1,0,0);
if(flag1 && flag2) ur = unite_rectangles(r1, r2);
else if(flag1) ur = r1;
else if(flag2) ur = r2;
if(!ur.is_valid()) return;
ren.prepare(unsigned(ur.x2 - ur.x2 + 2));
ren.prepare();
// Reset the scanlines and get two first ones
//-----------------
@@ -1154,7 +1166,7 @@ namespace agg
// Get the bounding box
//----------------
rect r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
// Reset the scanlines and get two first ones
//-----------------
@@ -1165,10 +1177,10 @@ namespace agg
if(flag2) flag2 = sg2.sweep_scanline(sl2);
ren.prepare(unsigned(sg1.max_x() - sg1.min_x() + 2));
ren.prepare();
// A fake span2 processor
sbool_add_span_empty<Scanline1, Scanline> add_span2;
sbool_add_span_empty<Scanline2, Scanline> add_span2;
// The main loop
// Here we synchronize the scanlines with
@@ -1376,6 +1388,34 @@ namespace agg
}
//--------------------------------------sbool_xor_shapes_abs_diff_aa
// Apply eXclusive OR to two anti-aliased scanline shapes.
// There's the absolute difference used to calculate
// Anti-Aliasing values, that is:
// a XOR b : abs(a-b)
// See intersect_shapes_aa for more comments
//----------
template<class ScanlineGen1,
class ScanlineGen2,
class Scanline1,
class Scanline2,
class Scanline,
class Renderer>
void sbool_xor_shapes_abs_diff_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
Scanline1& sl1, Scanline2& sl2,
Scanline& sl, Renderer& ren)
{
sbool_add_span_aa<Scanline1, Scanline> add_functor1;
sbool_add_span_aa<Scanline2, Scanline> add_functor2;
sbool_xor_spans_aa<Scanline1,
Scanline2,
Scanline,
sbool_xor_formula_abs_diff> combine_functor;
sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
add_functor1, add_functor2, combine_functor);
}
//--------------------------------------------------sbool_xor_shapes_bin
// Apply eXclusive OR to two binary scanline shapes (without anti-aliasing).
@@ -1459,6 +1499,7 @@ namespace agg
sbool_and, //----sbool_and
sbool_xor, //----sbool_xor
sbool_xor_saddle, //----sbool_xor_saddle
sbool_xor_abs_diff, //----sbool_xor_abs_diff
sbool_a_minus_b, //----sbool_a_minus_b
sbool_b_minus_a //----sbool_b_minus_a
};
@@ -1482,12 +1523,13 @@ namespace agg
{
switch(op)
{
case sbool_or : sbool_unite_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_and : sbool_intersect_shapes_bin(sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_xor :
case sbool_xor_saddle: sbool_xor_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_a_minus_b : sbool_subtract_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_b_minus_a : sbool_subtract_shapes_bin (sg2, sg1, sl2, sl1, sl, ren); break;
case sbool_or : sbool_unite_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_and : sbool_intersect_shapes_bin(sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_xor :
case sbool_xor_saddle :
case sbool_xor_abs_diff: sbool_xor_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_a_minus_b : sbool_subtract_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_b_minus_a : sbool_subtract_shapes_bin (sg2, sg1, sl2, sl1, sl, ren); break;
}
}
@@ -1508,12 +1550,13 @@ namespace agg
{
switch(op)
{
case sbool_or : sbool_unite_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_and : sbool_intersect_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_xor : sbool_xor_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_xor_saddle: sbool_xor_shapes_saddle_aa(sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_a_minus_b : sbool_subtract_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_b_minus_a : sbool_subtract_shapes_aa (sg2, sg1, sl2, sl1, sl, ren); break;
case sbool_or : sbool_unite_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_and : sbool_intersect_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_xor : sbool_xor_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_xor_saddle : sbool_xor_shapes_saddle_aa (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_xor_abs_diff: sbool_xor_shapes_abs_diff_aa(sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_a_minus_b : sbool_subtract_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
case sbool_b_minus_a : sbool_subtract_shapes_aa (sg2, sg1, sl2, sl1, sl, ren); break;
}
}
+253 -121
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -16,180 +16,312 @@
// Class scanline_p - a general purpose scanline container with packed spans.
//
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_P_INCLUDED
#define AGG_SCANLINE_P_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
namespace agg
{
//==============================================================scanline_p
//=============================================================scanline_p8
//
// This is a general purpose scaline container which supports the interface
// used in the rasterizer::render(). See description of agg_scanline_u
// used in the rasterizer::render(). See description of scanline_u8
// for details.
//
//------------------------------------------------------------------------
template<class T> class scanline_p
class scanline_p8
{
public:
typedef T cover_type;
typedef scanline_p8 self_type;
typedef int8u cover_type;
typedef int16 coord_type;
//--------------------------------------------------------------------
struct span
{
int16 x;
int16 len; // If negative, it's a solid span, covers is valid
const T* covers;
coord_type x;
coord_type len; // If negative, it's a solid span, covers is valid
const cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
~scanline_p()
{
delete [] m_spans;
delete [] m_covers;
}
scanline_p() :
m_max_len(0),
scanline_p8() :
m_last_x(0x7FFFFFF0),
m_covers(0),
m_covers(),
m_cover_ptr(0),
m_spans(0),
m_spans(),
m_cur_span(0)
{
}
void reset(int min_x, int max_x);
void add_cell(int x, unsigned cover);
void add_cells(int x, unsigned len, const T* covers);
void add_span(int x, unsigned len, unsigned cover);
void finalize(int y) { m_y = y; }
void reset_spans();
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 3;
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_cur_span = &m_spans[0];
m_cur_span->len = 0;
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover)
{
*m_cover_ptr = (cover_type)cover;
if(x == m_last_x+1 && m_cur_span->len > 0)
{
m_cur_span->len++;
}
else
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = 1;
}
m_last_x = x;
m_cover_ptr++;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const cover_type* covers)
{
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
if(x == m_last_x+1 && m_cur_span->len > 0)
{
m_cur_span->len += (int16)len;
}
else
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = (int16)len;
}
m_cover_ptr += len;
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
if(x == m_last_x+1 &&
m_cur_span->len < 0 &&
cover == *m_cur_span->covers)
{
m_cur_span->len -= (int16)len;
}
else
{
*m_cover_ptr = (cover_type)cover;
m_cur_span++;
m_cur_span->covers = m_cover_ptr++;
m_cur_span->x = (int16)x;
m_cur_span->len = (int16)(-int(len));
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_cur_span = &m_spans[0];
m_cur_span->len = 0;
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - m_spans); }
const_iterator begin() const { return m_spans + 1; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
private:
scanline_p(const scanline_p<T>&);
const scanline_p<T>& operator = (const scanline_p<T>&);
scanline_p8(const self_type&);
const self_type& operator = (const self_type&);
unsigned m_max_len;
int m_last_x;
int m_y;
T* m_covers;
T* m_cover_ptr;
span* m_spans;
span* m_cur_span;
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
cover_type* m_cover_ptr;
pod_array<span> m_spans;
span* m_cur_span;
};
//------------------------------------------------------------------------
template<class T>
void scanline_p<T>::reset(int min_x, int max_x)
//==========================================================scanline32_p8
class scanline32_p8
{
unsigned max_len = max_x - min_x + 3;
if(max_len > m_max_len)
public:
typedef scanline32_p8 self_type;
typedef int8u cover_type;
typedef int32 coord_type;
struct span
{
delete [] m_spans;
delete [] m_covers;
m_covers = new T [max_len];
m_spans = new span [max_len];
m_max_len = max_len;
}
m_last_x = 0x7FFFFFF0;
m_cover_ptr = m_covers;
m_cur_span = m_spans;
m_cur_span->len = 0;
}
span() {}
span(coord_type x_, coord_type len_, const cover_type* covers_) :
x(x_), len(len_), covers(covers_) {}
coord_type x;
coord_type len; // If negative, it's a solid span, covers is valid
const cover_type* covers;
};
typedef pod_bvector<span, 4> span_array_type;
//------------------------------------------------------------------------
template<class T>
void scanline_p<T>::reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cover_ptr = m_covers;
m_cur_span = m_spans;
m_cur_span->len = 0;
}
//------------------------------------------------------------------------
template<class T>
void scanline_p<T>::add_cell(int x, unsigned cover)
{
*m_cover_ptr = (T)cover;
if(x == m_last_x+1 && m_cur_span->len > 0)
//--------------------------------------------------------------------
class const_iterator
{
m_cur_span->len++;
}
else
public:
const_iterator(const span_array_type& spans) :
m_spans(spans),
m_span_idx(0)
{}
const span& operator*() const { return m_spans[m_span_idx]; }
const span* operator->() const { return &m_spans[m_span_idx]; }
void operator ++ () { ++m_span_idx; }
private:
const span_array_type& m_spans;
unsigned m_span_idx;
};
//--------------------------------------------------------------------
scanline32_p8() :
m_max_len(0),
m_last_x(0x7FFFFFF0),
m_covers(),
m_cover_ptr(0)
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = 1;
}
m_last_x = x;
m_cover_ptr++;
}
//------------------------------------------------------------------------
template<class T>
void scanline_p<T>::add_cells(int x, unsigned len, const T* covers)
{
memcpy(m_cover_ptr, covers, len * sizeof(T));
if(x == m_last_x+1 && m_cur_span->len > 0)
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
m_cur_span->len += (int16)len;
unsigned max_len = max_x - min_x + 3;
if(max_len > m_covers.size())
{
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_spans.remove_all();
}
else
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover)
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = (int16)len;
*m_cover_ptr = cover_type(cover);
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
{
m_spans.last().len++;
}
else
{
m_spans.add(span(coord_type(x), 1, m_cover_ptr));
}
m_last_x = x;
m_cover_ptr++;
}
m_cover_ptr += len;
m_last_x = x + len - 1;
}
//------------------------------------------------------------------------
template<class T>
void scanline_p<T>::add_span(int x, unsigned len, unsigned cover)
{
if(x == m_last_x+1 &&
m_cur_span->len < 0 &&
cover == *m_cur_span->covers)
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const cover_type* covers)
{
m_cur_span->len -= (int16)len;
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
{
m_spans.last().len += coord_type(len);
}
else
{
m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
}
m_cover_ptr += len;
m_last_x = x + len - 1;
}
else
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
*m_cover_ptr = (T)cover;
m_cur_span++;
m_cur_span->covers = m_cover_ptr++;
m_cur_span->x = (int16)x;
m_cur_span->len = -((int16)len);
if(x == m_last_x+1 &&
m_spans.size() &&
m_spans.last().len < 0 &&
cover == *m_spans.last().covers)
{
m_spans.last().len -= coord_type(len);
}
else
{
*m_cover_ptr = cover_type(cover);
m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
}
m_last_x = x + len - 1;
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_spans.remove_all();
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return m_spans.size(); }
const_iterator begin() const { return const_iterator(m_spans); }
private:
scanline32_p8(const self_type&);
const self_type& operator = (const self_type&);
unsigned m_max_len;
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
cover_type* m_cover_ptr;
span_array_type m_spans;
};
//=============================================================scanline_p8
typedef scanline_p<int8u> scanline_p8;
//============================================================scanline_p16
typedef scanline_p<int16u> scanline_p16;
//============================================================scanline_p32
typedef scanline_p<int32u> scanline_p32;
}
+90 -71
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -12,6 +12,14 @@
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED
#define AGG_SCANLINE_STORAGE_AA_INCLUDED
@@ -20,7 +28,6 @@
#include <stdlib.h>
#include <math.h>
#include "agg_array.h"
#include "agg_render_scanlines.h"
namespace agg
@@ -76,7 +83,8 @@ namespace agg
int i;
for(i = m_extra_storage.size()-1; i >= 0; --i)
{
delete [] m_extra_storage[(unsigned)i].ptr;
pod_allocator<T>::deallocate(m_extra_storage[i].ptr,
m_extra_storage[i].len);
}
m_extra_storage.remove_all();
m_cells.remove_all();
@@ -94,7 +102,7 @@ namespace agg
}
extra_span s;
s.len = num_cells;
s.ptr = new T [num_cells];
s.ptr = pod_allocator<T>::allocate(num_cells);
memcpy(s.ptr, cells, sizeof(T) * num_cells);
m_extra_storage.add(s);
return -int(m_extra_storage.size());
@@ -135,14 +143,14 @@ namespace agg
const extra_span& src = v.m_extra_storage[i];
extra_span dst;
dst.len = src.len;
dst.ptr = new T [dst.len];
dst.ptr = pod_allocator<T>::allocate(dst.len);
memcpy(dst.ptr, src.ptr, dst.len * sizeof(T));
m_extra_storage.add(dst);
}
}
pod_deque<T, 12> m_cells;
pod_deque<extra_span, 6> m_extra_storage;
pod_bvector<T, 12> m_cells;
pod_bvector<extra_span, 6> m_extra_storage;
};
@@ -159,8 +167,8 @@ namespace agg
//---------------------------------------------------------------
struct span_data
{
int16 x;
int16 len; // If negative, it's a solid span, covers is valid
int32 x;
int32 len; // If negative, it's a solid span, covers is valid
int covers_id; // The index of the cells in the scanline_cell_storage
};
@@ -184,11 +192,12 @@ namespace agg
public:
struct span
{
int16 x;
int16 len; // If negative, it's a solid span, covers is valid
int32 x;
int32 len; // If negative, it's a solid span, covers is valid
const T* covers;
};
const_iterator() : m_storage(0) {}
const_iterator(const embedded_scanline& sl) :
m_storage(sl.m_storage),
m_span_idx(sl.m_scanline.start_span)
@@ -270,7 +279,7 @@ namespace agg
// Renderer Interface
//---------------------------------------------------------------
void prepare(unsigned)
void prepare()
{
m_covers.remove_all();
m_scanlines.remove_all();
@@ -297,7 +306,7 @@ namespace agg
typename Scanline::const_iterator span_iterator = sl.begin();
unsigned num_spans = sl_this.num_spans;
do
for(;;)
{
span_data sp;
@@ -312,9 +321,9 @@ namespace agg
int x2 = sp.x + len - 1;
if(x1 < m_min_x) m_min_x = x1;
if(x2 > m_max_x) m_max_x = x2;
if(--num_spans == 0) break;
++span_iterator;
}
while(--num_spans);
m_scanlines.add(sl_this);
}
@@ -388,11 +397,11 @@ namespace agg
unsigned byte_size() const
{
unsigned i;
unsigned size = sizeof(int16) * 4; // min_x, min_y, max_x, max_y
unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
for(i = 0; i < m_scanlines.size(); ++i)
{
size += sizeof(int16) * 3; // scanline size in bytes, Y, num_spans
size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans
const scanline_data& sl_this = m_scanlines[i];
@@ -402,7 +411,7 @@ namespace agg
{
const span_data& sp = m_spans[span_idx++];
size += sizeof(int16) * 2; // X, span_len
size += sizeof(int32) * 2; // X, span_len
if(sp.len < 0)
{
size += sizeof(T); // cover
@@ -419,10 +428,12 @@ namespace agg
//---------------------------------------------------------------
static void write_int16(int8u* dst, int16 val)
static void write_int32(int8u* dst, int32 val)
{
dst[0] = ((const int8u*)&val)[0];
dst[1] = ((const int8u*)&val)[1];
dst[2] = ((const int8u*)&val)[2];
dst[3] = ((const int8u*)&val)[3];
}
@@ -431,27 +442,27 @@ namespace agg
{
unsigned i;
write_int16(data, int16u(min_x())); // min_x
data += sizeof(int16u);
write_int16(data, int16u(min_y())); // min_y
data += sizeof(int16u);
write_int16(data, int16u(max_x())); // max_x
data += sizeof(int16u);
write_int16(data, int16u(max_y())); // max_y
data += sizeof(int16u);
write_int32(data, min_x()); // min_x
data += sizeof(int32);
write_int32(data, min_y()); // min_y
data += sizeof(int32);
write_int32(data, max_x()); // max_x
data += sizeof(int32);
write_int32(data, max_y()); // max_y
data += sizeof(int32);
for(i = 0; i < m_scanlines.size(); ++i)
{
const scanline_data& sl_this = m_scanlines[i];
int8u* size_ptr = data;
data += sizeof(int16); // Reserve space for scanline size in bytes
data += sizeof(int32); // Reserve space for scanline size in bytes
write_int16(data, int16(sl_this.y)); // Y
data += sizeof(int16);
write_int32(data, sl_this.y); // Y
data += sizeof(int32);
write_int16(data, int16(sl_this.num_spans)); // num_spans
data += sizeof(int16);
write_int32(data, sl_this.num_spans); // num_spans
data += sizeof(int32);
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
@@ -460,11 +471,11 @@ namespace agg
const span_data& sp = m_spans[span_idx++];
const T* covers = covers_by_index(sp.covers_id);
write_int16(data, int16(sp.x)); // X
data += sizeof(int16);
write_int32(data, sp.x); // X
data += sizeof(int32);
write_int16(data, int16(sp.len)); // span_len
data += sizeof(int16);
write_int32(data, sp.len); // span_len
data += sizeof(int32);
if(sp.len < 0)
{
@@ -478,7 +489,7 @@ namespace agg
}
}
while(--num_spans);
write_int16(size_ptr, int16(unsigned(data - size_ptr)));
write_int32(size_ptr, int32(unsigned(data - size_ptr)));
}
}
@@ -502,9 +513,9 @@ namespace agg
}
private:
scanline_cell_storage<T> m_covers;
pod_deque<span_data, 10> m_spans;
pod_deque<scanline_data, 8> m_scanlines;
scanline_cell_storage<T> m_covers;
pod_bvector<span_data, 10> m_spans;
pod_bvector<scanline_data, 8> m_scanlines;
span_data m_fake_span;
scanline_data m_fake_scanline;
int m_min_x;
@@ -540,11 +551,12 @@ namespace agg
public:
struct span
{
int16 x;
int16 len; // If negative, it's a solid span, "covers" is valid
int32 x;
int32 len; // If negative, it's a solid span, "covers" is valid
const T* covers;
};
const_iterator() : m_ptr(0) {}
const_iterator(const embedded_scanline& sl) :
m_ptr(sl.m_ptr),
m_dx(sl.m_dx)
@@ -569,18 +581,20 @@ namespace agg
}
private:
int read_int16()
int read_int32()
{
int16 val;
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
void init_span()
{
m_span.x = read_int16() + m_dx;
m_span.len = read_int16();
m_span.x = read_int32() + m_dx;
m_span.len = read_int32();
m_span.covers = m_ptr;
}
@@ -604,11 +618,13 @@ namespace agg
private:
//-----------------------------------------------------------------
int read_int16()
int read_int32()
{
int16 val;
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -617,8 +633,8 @@ namespace agg
void init(const int8u* ptr, int dx, int dy)
{
m_ptr = ptr;
m_y = read_int16() + dy;
m_num_spans = unsigned(read_int16());
m_y = read_int32() + dy;
m_num_spans = unsigned(read_int32());
m_dx = dx;
}
@@ -651,8 +667,8 @@ namespace agg
m_data(data),
m_end(data + size),
m_ptr(data),
m_dx(int(floor(dx + 0.5))),
m_dy(int(floor(dy + 0.5))),
m_dx(iround(dx)),
m_dy(iround(dy)),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
@@ -665,8 +681,8 @@ namespace agg
m_data = data;
m_end = data + size;
m_ptr = data;
m_dx = int(floor(dx + 0.5));
m_dy = int(floor(dy + 0.5));
m_dx = iround(dx);
m_dy = iround(dy);
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
@@ -675,20 +691,24 @@ namespace agg
private:
//--------------------------------------------------------------------
int read_int16()
int read_int32()
{
int16 val;
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
//--------------------------------------------------------------------
unsigned read_int16u()
unsigned read_int32u()
{
int16u val;
int32u val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -700,13 +720,12 @@ namespace agg
m_ptr = m_data;
if(m_ptr < m_end)
{
m_min_x = read_int16() + m_dx;
m_min_y = read_int16() + m_dy;
m_max_x = read_int16() + m_dx;
m_max_y = read_int16() + m_dy;
return true;
m_min_x = read_int32() + m_dx;
m_min_y = read_int32() + m_dy;
m_max_x = read_int32() + m_dx;
m_max_y = read_int32() + m_dy;
}
return false;
return m_ptr < m_end;
}
//--------------------------------------------------------------------
@@ -723,14 +742,14 @@ namespace agg
{
if(m_ptr >= m_end) return false;
read_int16(); // Skip scanline size in bytes
int y = read_int16() + m_dy;
unsigned num_spans = read_int16();
read_int32(); // Skip scanline size in bytes
int y = read_int32() + m_dy;
unsigned num_spans = read_int32();
do
{
int x = read_int16() + m_dx;
int len = read_int16();
int x = read_int32() + m_dx;
int len = read_int32();
if(len < 0)
{
@@ -763,9 +782,9 @@ namespace agg
{
if(m_ptr >= m_end) return false;
unsigned byte_size = read_int16u();
unsigned byte_size = read_int32u();
sl.init(m_ptr, m_dx, m_dy);
m_ptr += byte_size - sizeof(int16);
m_ptr += byte_size - sizeof(int32);
}
while(sl.num_spans() == 0);
return true;
+79 -62
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -12,6 +12,15 @@
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
#define AGG_SCANLINE_STORAGE_BIN_INCLUDED
@@ -20,7 +29,6 @@
#include <stdlib.h>
#include <math.h>
#include "agg_array.h"
#include "agg_render_scanlines.h"
namespace agg
@@ -33,8 +41,8 @@ namespace agg
//---------------------------------------------------------------
struct span_data
{
int16 x;
int16 len;
int32 x;
int32 len;
};
//---------------------------------------------------------------
@@ -55,6 +63,7 @@ namespace agg
class const_iterator
{
public:
const_iterator() : m_storage(0) {}
const_iterator(const embedded_scanline& sl) :
m_storage(sl.m_storage),
m_span_idx(sl.m_scanline.start_span)
@@ -126,7 +135,7 @@ namespace agg
// Renderer Interface
//---------------------------------------------------------------
void prepare(unsigned)
void prepare()
{
m_scanlines.remove_all();
m_spans.remove_all();
@@ -152,19 +161,19 @@ namespace agg
typename Scanline::const_iterator span_iterator = sl.begin();
unsigned num_spans = sl_this.num_spans;
do
for(;;)
{
span_data sp;
sp.x = span_iterator->x;
sp.len = (int16)abs((int)(span_iterator->len));
sp.len = (int32)abs((int)(span_iterator->len));
m_spans.add(sp);
int x1 = sp.x;
int x2 = sp.x + sp.len - 1;
if(x1 < m_min_x) m_min_x = x1;
if(x2 > m_max_x) m_max_x = x2;
if(--num_spans == 0) break;
++span_iterator;
}
while(--num_spans);
m_scanlines.add(sl_this);
}
@@ -232,22 +241,24 @@ namespace agg
unsigned byte_size() const
{
unsigned i;
unsigned size = sizeof(int16) * 4; // min_x, min_y, max_x, max_y
unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
for(i = 0; i < m_scanlines.size(); ++i)
{
size += sizeof(int16) * 2 + // Y, num_spans
unsigned(m_scanlines[i].num_spans) * sizeof(int16) * 2; // X, span_len
size += sizeof(int32) * 2 + // Y, num_spans
unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len
}
return size;
}
//---------------------------------------------------------------
static void write_int16(int8u* dst, int16 val)
static void write_int32(int8u* dst, int32 val)
{
dst[0] = ((const int8u*)&val)[0];
dst[1] = ((const int8u*)&val)[1];
dst[2] = ((const int8u*)&val)[2];
dst[3] = ((const int8u*)&val)[3];
}
@@ -256,24 +267,24 @@ namespace agg
{
unsigned i;
write_int16(data, int16u(min_x())); // min_x
data += sizeof(int16u);
write_int16(data, int16u(min_y())); // min_y
data += sizeof(int16u);
write_int16(data, int16u(max_x())); // max_x
data += sizeof(int16u);
write_int16(data, int16u(max_y())); // max_y
data += sizeof(int16u);
write_int32(data, min_x()); // min_x
data += sizeof(int32);
write_int32(data, min_y()); // min_y
data += sizeof(int32);
write_int32(data, max_x()); // max_x
data += sizeof(int32);
write_int32(data, max_y()); // max_y
data += sizeof(int32);
for(i = 0; i < m_scanlines.size(); ++i)
{
const scanline_data& sl_this = m_scanlines[i];
write_int16(data, int16(sl_this.y)); // Y
data += sizeof(int16);
write_int32(data, sl_this.y); // Y
data += sizeof(int32);
write_int16(data, int16(sl_this.num_spans)); // num_spans
data += sizeof(int16);
write_int32(data, sl_this.num_spans); // num_spans
data += sizeof(int32);
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
@@ -281,11 +292,11 @@ namespace agg
{
const span_data& sp = m_spans[span_idx++];
write_int16(data, int16(sp.x)); // X
data += sizeof(int16);
write_int32(data, sp.x); // X
data += sizeof(int32);
write_int16(data, int16(sp.len)); // len
data += sizeof(int16);
write_int32(data, sp.len); // len
data += sizeof(int32);
}
while(--num_spans);
}
@@ -306,8 +317,8 @@ namespace agg
private:
pod_deque<span_data, 10> m_spans;
pod_deque<scanline_data, 8> m_scanlines;
pod_bvector<span_data, 10> m_spans;
pod_bvector<scanline_data, 8> m_scanlines;
span_data m_fake_span;
scanline_data m_fake_scanline;
int m_min_x;
@@ -346,16 +357,17 @@ namespace agg
public:
struct span
{
int16 x;
int16 len;
int32 x;
int32 len;
};
const_iterator() : m_ptr(0) {}
const_iterator(const embedded_scanline& sl) :
m_ptr(sl.m_ptr),
m_dx(sl.m_dx)
{
m_span.x = read_int16() + m_dx;
m_span.len = read_int16();
m_span.x = read_int32() + m_dx;
m_span.len = read_int32();
}
const span& operator*() const { return m_span; }
@@ -363,16 +375,18 @@ namespace agg
void operator ++ ()
{
m_span.x = read_int16() + m_dx;
m_span.len = read_int16();
m_span.x = read_int32() + m_dx;
m_span.len = read_int32();
}
private:
int read_int16()
int read_int32()
{
int16 val;
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -396,11 +410,13 @@ namespace agg
private:
//----------------------------------------------------------------
int read_int16()
int read_int32()
{
int16 val;
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -409,8 +425,8 @@ namespace agg
void init(const int8u* ptr, int dx, int dy)
{
m_ptr = ptr;
m_y = read_int16() + dy;
m_num_spans = unsigned(read_int16());
m_y = read_int32() + dy;
m_num_spans = unsigned(read_int32());
m_dx = dx;
}
@@ -443,8 +459,8 @@ namespace agg
m_data(data),
m_end(data + size),
m_ptr(data),
m_dx(int(floor(dx + 0.5))),
m_dy(int(floor(dy + 0.5))),
m_dx(iround(dx)),
m_dy(iround(dy)),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
@@ -457,8 +473,8 @@ namespace agg
m_data = data;
m_end = data + size;
m_ptr = data;
m_dx = int(floor(dx + 0.5));
m_dy = int(floor(dy + 0.5));
m_dx = iround(dx);
m_dy = iround(dy);
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
@@ -467,11 +483,13 @@ namespace agg
private:
//--------------------------------------------------------------------
int read_int16()
int read_int32()
{
int16 val;
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -483,13 +501,12 @@ namespace agg
m_ptr = m_data;
if(m_ptr < m_end)
{
m_min_x = read_int16() + m_dx;
m_min_y = read_int16() + m_dy;
m_max_x = read_int16() + m_dx;
m_max_y = read_int16() + m_dy;
return true;
m_min_x = read_int32() + m_dx;
m_min_y = read_int32() + m_dy;
m_max_x = read_int32() + m_dx;
m_max_y = read_int32() + m_dy;
}
return false;
return m_ptr < m_end;
}
//--------------------------------------------------------------------
@@ -506,13 +523,13 @@ namespace agg
{
if(m_ptr >= m_end) return false;
int y = read_int16() + m_dy;
unsigned num_spans = read_int16();
int y = read_int32() + m_dy;
unsigned num_spans = read_int32();
do
{
int x = read_int16() + m_dx;
int len = read_int16();
int x = read_int32() + m_dx;
int len = read_int32();
if(len < 0) len = -len;
sl.add_span(x, unsigned(len), cover_full);
@@ -541,9 +558,9 @@ namespace agg
// Jump to the next scanline
//--------------------------
read_int16(); // Y
int num_spans = read_int16(); // num_spans
m_ptr += num_spans * sizeof(int16) * 2;
read_int32(); // Y
int num_spans = read_int32(); // num_spans
m_ptr += num_spans * sizeof(int32) * 2;
}
while(sl.num_spans() == 0);
return true;
+343 -167
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -12,20 +12,27 @@
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_U_INCLUDED
#define AGG_SCANLINE_U_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_array.h"
namespace agg
{
//==============================================================scanline_u
//=============================================================scanline_u8
//
// Unpacked scanline container class
//
// This class is used to transfer data from a scanline rastyerizer
// This class is used to transfer data from a scanline rasterizer
// to the rendering buffer. It's organized very simple. The class stores
// information of horizontal spans to render it into a pixel-map buffer.
// Each span has staring X, length, and an array of bytes that determine the
@@ -94,21 +101,23 @@ namespace agg
//
// The question is: why should we accumulate the whole scanline when we
// could render just separate spans when they're ready?
// That's because using the scaline is generally faster. When is consists
// That's because using the scanline is generally faster. When is consists
// of more than one span the conditions for the processor cash system
// are better, because switching between two different areas of memory
// (that can be very large) occures less frequently.
// (that can be very large) occurs less frequently.
//------------------------------------------------------------------------
template<class T> class scanline_u
class scanline_u8
{
public:
typedef T cover_type;
typedef scanline_u8 self_type;
typedef int8u cover_type;
typedef int16 coord_type;
//--------------------------------------------------------------------
struct span
{
int16 x;
int16 len;
coord_type x;
coord_type len;
cover_type* covers;
};
@@ -116,181 +125,147 @@ namespace agg
typedef const span* const_iterator;
//--------------------------------------------------------------------
~scanline_u();
scanline_u();
scanline_u8() :
m_min_x(0),
m_last_x(0x7FFFFFF0),
m_cur_span(0)
{}
void reset(int min_x, int max_x);
void add_cell(int x, unsigned cover);
void add_cells(int x, unsigned len, const T* covers);
void add_span(int x, unsigned len, unsigned cover);
void finalize(int y) { m_y = y; }
void reset_spans();
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 2;
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_min_x = min_x;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover)
{
x -= m_min_x;
m_covers[x] = (cover_type)cover;
if(x == m_last_x+1)
{
m_cur_span->len++;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = 1;
m_cur_span->covers = &m_covers[x];
}
m_last_x = x;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const cover_type* covers)
{
x -= m_min_x;
memcpy(&m_covers[x], covers, len * sizeof(cover_type));
if(x == m_last_x+1)
{
m_cur_span->len += (coord_type)len;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = (coord_type)len;
m_cur_span->covers = &m_covers[x];
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
x -= m_min_x;
memset(&m_covers[x], cover, len);
if(x == m_last_x+1)
{
m_cur_span->len += (coord_type)len;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = (coord_type)len;
m_cur_span->covers = &m_covers[x];
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - m_spans); }
const_iterator begin() const { return m_spans + 1; }
iterator begin() { return m_spans + 1; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
iterator begin() { return &m_spans[1]; }
private:
scanline_u<T>(const scanline_u<T>&);
const scanline_u<T>& operator = (const scanline_u<T>&);
scanline_u8(const self_type&);
const self_type& operator = (const self_type&);
private:
int m_min_x;
unsigned m_max_len;
int m_last_x;
int m_y;
cover_type* m_covers;
span* m_spans;
span* m_cur_span;
int m_min_x;
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
pod_array<span> m_spans;
span* m_cur_span;
};
//------------------------------------------------------------------------
template<class T> scanline_u<T>::~scanline_u()
{
delete [] m_spans;
delete [] m_covers;
}
//------------------------------------------------------------------------
template<class T> scanline_u<T>::scanline_u() :
m_min_x(0),
m_max_len(0),
m_last_x(0x7FFFFFF0),
m_covers(0),
m_spans(0),
m_cur_span(0)
{
}
//------------------------------------------------------------------------
template<class T> void scanline_u<T>::reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 2;
if(max_len > m_max_len)
{
delete [] m_spans;
delete [] m_covers;
m_covers = new cover_type [max_len];
m_spans = new span [max_len];
m_max_len = max_len;
}
m_last_x = 0x7FFFFFF0;
m_min_x = min_x;
m_cur_span = m_spans;
}
//------------------------------------------------------------------------
template<class T> inline void scanline_u<T>::reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = m_spans;
}
//------------------------------------------------------------------------
template<class T> inline void scanline_u<T>::add_cell(int x, unsigned cover)
{
x -= m_min_x;
m_covers[x] = (unsigned char)cover;
if(x == m_last_x+1)
{
m_cur_span->len++;
}
else
{
m_cur_span++;
m_cur_span->x = (int16)(x + m_min_x);
m_cur_span->len = 1;
m_cur_span->covers = m_covers + x;
}
m_last_x = x;
}
//------------------------------------------------------------------------
template<class T> void scanline_u<T>::add_cells(int x, unsigned len, const T* covers)
{
x -= m_min_x;
memcpy(m_covers + x, covers, len * sizeof(T));
if(x == m_last_x+1)
{
m_cur_span->len += (int16)len;
}
else
{
m_cur_span++;
m_cur_span->x = (int16)(x + m_min_x);
m_cur_span->len = (int16)len;
m_cur_span->covers = m_covers + x;
}
m_last_x = x + len - 1;
}
//------------------------------------------------------------------------
template<class T> void scanline_u<T>::add_span(int x, unsigned len, unsigned cover)
{
x -= m_min_x;
memset(m_covers + x, cover, len);
if(x == m_last_x+1)
{
m_cur_span->len += (int16)len;
}
else
{
m_cur_span++;
m_cur_span->x = (int16)(x + m_min_x);
m_cur_span->len = (int16)len;
m_cur_span->covers = m_covers + x;
}
m_last_x = x + len - 1;
}
//=============================================================scanline_u8
typedef scanline_u<int8u> scanline_u8;
//============================================================scanline_u16
typedef scanline_u<int16u> scanline_u16;
//============================================================scanline_u32
typedef scanline_u<int32u> scanline_u32;
//=============================================================scanline_am
//==========================================================scanline_u8_am
//
// The scanline container with alpha-masking
//
//------------------------------------------------------------------------
template<class AlphaMask, class CoverT>
class scanline_am : public scanline_u<CoverT>
template<class AlphaMask>
class scanline_u8_am : public scanline_u8
{
public:
typedef AlphaMask alpha_mask_type;
typedef CoverT cover_type;
typedef scanline_u<CoverT> scanline_type;
typedef scanline_u8 base_type;
typedef AlphaMask alpha_mask_type;
typedef base_type::cover_type cover_type;
typedef base_type::coord_type coord_type;
scanline_am() : scanline_type(), m_alpha_mask(0) {}
scanline_am(const AlphaMask& am) : scanline_type(), m_alpha_mask(&am) {}
scanline_u8_am() : base_type(), m_alpha_mask(0) {}
scanline_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {}
//--------------------------------------------------------------------
void finalize(int span_y)
{
scanline_u<CoverT>::finalize(span_y);
base_type::finalize(span_y);
if(m_alpha_mask)
{
typename scanline_type::iterator span = scanline_type::begin();
unsigned count = scanline_type::num_spans();
typename base_type::iterator span = base_type::begin();
unsigned count = base_type::num_spans();
do
{
m_alpha_mask->combine_hspan(span->x,
scanline_type::y(),
base_type::y(),
span->covers,
span->len);
++span;
@@ -304,19 +279,220 @@ namespace agg
};
//==========================================================scanline_u8_am
template<class AlphaMask>
class scanline_u8_am : public scanline_am<AlphaMask, int8u>
//===========================================================scanline32_u8
class scanline32_u8
{
public:
typedef AlphaMask alpha_mask_type;
typedef int8u cover_type;
typedef scanline_am<alpha_mask_type, cover_type> self_type;
typedef scanline32_u8 self_type;
typedef int8u cover_type;
typedef int32 coord_type;
scanline_u8_am() : self_type() {}
scanline_u8_am(const AlphaMask& am) : self_type(am) {}
//--------------------------------------------------------------------
struct span
{
span() {}
span(coord_type x_, coord_type len_, cover_type* covers_) :
x(x_), len(len_), covers(covers_) {}
coord_type x;
coord_type len;
cover_type* covers;
};
typedef pod_bvector<span, 4> span_array_type;
//--------------------------------------------------------------------
class const_iterator
{
public:
const_iterator(const span_array_type& spans) :
m_spans(spans),
m_span_idx(0)
{}
const span& operator*() const { return m_spans[m_span_idx]; }
const span* operator->() const { return &m_spans[m_span_idx]; }
void operator ++ () { ++m_span_idx; }
private:
const span_array_type& m_spans;
unsigned m_span_idx;
};
//--------------------------------------------------------------------
class iterator
{
public:
iterator(span_array_type& spans) :
m_spans(spans),
m_span_idx(0)
{}
span& operator*() { return m_spans[m_span_idx]; }
span* operator->() { return &m_spans[m_span_idx]; }
void operator ++ () { ++m_span_idx; }
private:
span_array_type& m_spans;
unsigned m_span_idx;
};
//--------------------------------------------------------------------
scanline32_u8() :
m_min_x(0),
m_last_x(0x7FFFFFF0),
m_covers()
{}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 2;
if(max_len > m_covers.size())
{
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_min_x = min_x;
m_spans.remove_all();
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover)
{
x -= m_min_x;
m_covers[x] = cover_type(cover);
if(x == m_last_x+1)
{
m_spans.last().len++;
}
else
{
m_spans.add(span(coord_type(x + m_min_x), 1, &m_covers[x]));
}
m_last_x = x;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const cover_type* covers)
{
x -= m_min_x;
memcpy(&m_covers[x], covers, len * sizeof(cover_type));
if(x == m_last_x+1)
{
m_spans.last().len += coord_type(len);
}
else
{
m_spans.add(span(coord_type(x + m_min_x),
coord_type(len),
&m_covers[x]));
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
x -= m_min_x;
memset(&m_covers[x], cover, len);
if(x == m_last_x+1)
{
m_spans.last().len += coord_type(len);
}
else
{
m_spans.add(span(coord_type(x + m_min_x),
coord_type(len),
&m_covers[x]));
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_spans.remove_all();
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return m_spans.size(); }
const_iterator begin() const { return const_iterator(m_spans); }
iterator begin() { return iterator(m_spans); }
private:
scanline32_u8(const self_type&);
const self_type& operator = (const self_type&);
private:
int m_min_x;
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
span_array_type m_spans;
};
//========================================================scanline32_u8_am
//
// The scanline container with alpha-masking
//
//------------------------------------------------------------------------
template<class AlphaMask>
class scanline32_u8_am : public scanline32_u8
{
public:
typedef scanline_u8 base_type;
typedef AlphaMask alpha_mask_type;
typedef base_type::cover_type cover_type;
typedef base_type::coord_type coord_type;
scanline32_u8_am() : base_type(), m_alpha_mask(0) {}
scanline32_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {}
//--------------------------------------------------------------------
void finalize(int span_y)
{
base_type::finalize(span_y);
if(m_alpha_mask)
{
typename base_type::iterator span = base_type::begin();
unsigned count = base_type::num_spans();
do
{
m_alpha_mask->combine_hspan(span->x,
base_type::y(),
span->covers,
span->len);
++span;
}
while(--count);
}
}
private:
const AlphaMask* m_alpha_mask;
};
}
#endif
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+2 -2
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
+14 -32
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -16,7 +16,7 @@
#ifndef AGG_SPAN_ALLOCATOR_INCLUDED
#define AGG_SPAN_ALLOCATOR_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
namespace agg
{
@@ -27,42 +27,24 @@ namespace agg
typedef ColorT color_type;
//--------------------------------------------------------------------
~span_allocator()
AGG_INLINE color_type* allocate(unsigned span_len)
{
delete [] m_span;
}
//--------------------------------------------------------------------
span_allocator() :
m_max_span_len(0),
m_span(0)
{
}
//--------------------------------------------------------------------
color_type* allocate(unsigned max_span_len)
{
if(max_span_len > m_max_span_len)
if(span_len > m_span.size())
{
delete [] m_span;
m_span = new color_type[m_max_span_len = max_span_len];
// To reduce the number of reallocs we align the
// span_len to 256 color elements.
// Well, I just like this number and it looks reasonable.
//-----------------------
m_span.resize(((span_len + 255) >> 8) << 8);
}
return m_span;
return &m_span[0];
}
//--------------------------------------------------------------------
color_type* span()
{
return m_span;
}
AGG_INLINE color_type* span() { return &m_span[0]; }
AGG_INLINE unsigned max_span_len() const { return m_span.size(); }
private:
//--------------------------------------------------------------------
span_allocator(const span_allocator<ColorT>&);
const span_allocator<ColorT>& operator = (const span_allocator<ColorT>&);
unsigned m_max_span_len;
color_type* m_span;
pod_array<color_type> m_span;
};
}
+16 -13
View File
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
// 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.
@@ -21,31 +21,34 @@
namespace agg
{
//----------------------------------------------------------span_converter
template<class SpanGenerator, class Conv> class span_converter
template<class SpanGenerator, class SpanConverter> class span_converter
{
public:
typedef typename SpanGenerator::color_type color_type;
span_converter(SpanGenerator& span_gen, Conv& conv) :
m_span_gen(&span_gen), m_conv(&conv) {}
span_converter(SpanGenerator& span_gen, SpanConverter& span_cnv) :
m_span_gen(&span_gen), m_span_cnv(&span_cnv) {}
void attach_generator(SpanGenerator& span_gen) { m_span_gen = &span_gen; }
void attach_converter(SpanConverter& span_cnv) { m_span_cnv = &span_cnv; }
//--------------------------------------------------------------------
void prepare(unsigned max_span_len)
{
m_span_gen->prepare(max_span_len);
void prepare()
{
m_span_gen->prepare();
m_span_cnv->prepare();
}
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
void generate(color_type* span, int x, int y, unsigned len)
{
color_type* span = m_span_gen->generate(x, y, len);
m_conv->convert(span, x, y, len);
return span;
m_span_gen->generate(span, x, y, len);
m_span_cnv->generate(span, x, y, len);
}
private:
SpanGenerator* m_span_gen;
Conv* m_conv;
SpanConverter* m_span_cnv;
};
}
-50
View File
@@ -1,50 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_SPAN_GENERATOR_INCLUDED
#define AGG_SPAN_GENERATOR_INCLUDED
#include "agg_basics.h"
#include "agg_span_allocator.h"
namespace agg
{
//==========================================================span_generator
template<class ColorT, class Allocator> class span_generator
{
public:
typedef ColorT color_type;
typedef Allocator alloc_type;
//--------------------------------------------------------------------
span_generator(alloc_type& alloc) : m_alloc(&alloc) {}
//--------------------------------------------------------------------
void allocator(alloc_type& alloc) { m_alloc = &alloc; }
alloc_type& allocator() { return *m_alloc; }
//--------------------------------------------------------------------
void prepare(unsigned max_span_len)
{
m_alloc->allocate(max_span_len);
}
private:
alloc_type* m_alloc;
};
}
#endif

Some files were not shown because too many files have changed in this diff Show More