* 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:
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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>&);
|
||||
|
||||
@@ -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>&
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>&
|
||||
|
||||
@@ -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>&
|
||||
|
||||
@@ -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>&
|
||||
|
||||
@@ -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>&
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>&
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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>&
|
||||
|
||||
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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){} };
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
+1327
-213
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+33
-28
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
Executable
+755
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user