diff --git a/headers/libs/agg/agg_alpha_mask_u8.h b/headers/libs/agg/agg_alpha_mask_u8.h index 0b166635e7..50081a88d8 100755 --- a/headers/libs/agg/agg_alpha_mask_u8.h +++ b/headers/libs/agg/agg_alpha_mask_u8.h @@ -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 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 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; diff --git a/headers/libs/agg/agg_arc.h b/headers/libs/agg/agg_arc.h index 2dff50876d..17e1d43473 100644 --- a/headers/libs/agg/agg_arc.h +++ b/headers/libs/agg/agg_arc.h @@ -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. diff --git a/headers/libs/agg/agg_array.h b/headers/libs/agg/agg_array.h index 70ec2855a4..8d56683840 100644 --- a/headers/libs/agg/agg_array.h +++ b/headers/libs/agg/agg_array.h @@ -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 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 pod_auto_array + { + public: + typedef T value_type; + typedef pod_auto_array 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 pod_auto_vector + { + public: + typedef T value_type; + typedef pod_auto_vector 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 pod_array { public: typedef T value_type; + typedef pod_array 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::deallocate(m_array, m_size); } + pod_array() : m_array(0), m_size(0) {} + + pod_array(unsigned size) : + m_array(pod_allocator::allocate(size)), + m_size(size) + {} + + pod_array(const self_type& v) : + m_array(pod_allocator::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::deallocate(m_array, m_size); + m_array = pod_allocator::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 pod_vector + { + public: + typedef T value_type; + + ~pod_vector() { pod_allocator::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&); - const pod_array& operator = (const pod_array&); + pod_vector(const pod_vector&); + const pod_vector& operator = (const pod_vector&); - 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 - void pod_array::capacity(unsigned cap, unsigned extra_tail) + void pod_vector::capacity(unsigned cap, unsigned extra_tail) { m_size = 0; if(cap > m_capacity) { - delete [] m_array; + pod_allocator::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::allocate(m_capacity) : 0; } } //------------------------------------------------------------------------ template - void pod_array::resize(unsigned new_size) + void pod_vector::allocate(unsigned size, unsigned extra_tail) + { + capacity(size, extra_tail); + m_size = size; + } + + + //------------------------------------------------------------------------ + template + void pod_vector::resize(unsigned new_size) { if(new_size > m_size) { if(new_size > m_capacity) { - T* data = new T[new_size]; + T* data = pod_allocator::allocate(new_size); memcpy(data, m_array, m_size * sizeof(T)); - delete [] m_array; + pod_allocator::deallocate(m_array, m_capacity); m_array = data; } } @@ -96,81 +258,75 @@ namespace agg } //------------------------------------------------------------------------ - template pod_array::pod_array(unsigned cap, unsigned extra_tail) : - m_size(0), m_capacity(0), m_array(0) - { - capacity(cap, extra_tail); - } + template pod_vector::pod_vector(unsigned cap, unsigned extra_tail) : + m_size(0), + m_capacity(cap + extra_tail), + m_array(pod_allocator::allocate(m_capacity)) {} //------------------------------------------------------------------------ - template pod_array::pod_array(const pod_array& v) : + template pod_vector::pod_vector(const pod_vector& 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::allocate(v.m_capacity) : 0) { memcpy(m_array, v.m_array, sizeof(T) * v.m_size); } //------------------------------------------------------------------------ - template const pod_array& - pod_array::operator = (const pod_array&v) + template const pod_vector& + pod_vector::operator = (const pod_vector&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 void pod_array::serialize(int8u* ptr) const + template void pod_vector::serialize(int8u* ptr) const { if(m_size) memcpy(ptr, m_array, m_size * sizeof(T)); } //------------------------------------------------------------------------ template - void pod_array::deserialize(const int8u* data, unsigned byte_size) + void pod_vector::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 pod_array_adaptor + template + void pod_vector::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 pod_deque + template 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& v); - const pod_deque& operator = (const pod_deque& v); + pod_bvector(const pod_bvector& v); + const pod_bvector& operator = (const pod_bvector& 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 pod_deque::~pod_deque() + template pod_bvector::~pod_bvector() { if(m_num_blocks) { T** blk = m_blocks + m_num_blocks - 1; while(m_num_blocks--) { - delete [] *blk; + pod_allocator::deallocate(*blk, block_size); --blk; } - delete [] m_blocks; } + pod_allocator::deallocate(m_blocks, m_max_blocks); } //------------------------------------------------------------------------ template - void pod_deque::free_tail(unsigned size) + void pod_bvector::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::deallocate(m_blocks[--m_num_blocks], block_size); + } + if(m_num_blocks == 0) + { + pod_allocator::deallocate(m_blocks, m_max_blocks); + m_blocks = 0; + m_max_blocks = 0; } m_size = size; } @@ -370,7 +549,7 @@ namespace agg //------------------------------------------------------------------------ - template pod_deque::pod_deque() : + template pod_bvector::pod_bvector() : m_size(0), m_num_blocks(0), m_max_blocks(0), @@ -382,7 +561,7 @@ namespace agg //------------------------------------------------------------------------ template - pod_deque::pod_deque(unsigned block_ptr_inc) : + pod_bvector::pod_bvector(unsigned block_ptr_inc) : m_size(0), m_num_blocks(0), m_max_blocks(0), @@ -394,17 +573,19 @@ namespace agg //------------------------------------------------------------------------ template - pod_deque::pod_deque(const pod_deque& v) : + pod_bvector::pod_bvector(const pod_bvector& 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::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::allocate(block_size); memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); } } @@ -412,7 +593,8 @@ namespace agg //------------------------------------------------------------------------ template - const pod_deque& pod_deque::operator = (const pod_deque& v) + const pod_bvector& + pod_bvector::operator = (const pod_bvector& v) { unsigned i; for(i = m_num_blocks; i < v.m_num_blocks; ++i) @@ -430,11 +612,11 @@ namespace agg //------------------------------------------------------------------------ template - void pod_deque::allocate_block(unsigned nb) + void pod_bvector::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::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::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::allocate(block_size); m_num_blocks++; } @@ -455,7 +637,7 @@ namespace agg //------------------------------------------------------------------------ template - inline T* pod_deque::data_ptr() + inline T* pod_bvector::data_ptr() { unsigned nb = m_size >> block_shift; if(nb >= m_num_blocks) @@ -469,7 +651,7 @@ namespace agg //------------------------------------------------------------------------ template - inline void pod_deque::add(const T& val) + inline void pod_bvector::add(const T& val) { *data_ptr() = val; ++m_size; @@ -478,7 +660,7 @@ namespace agg //------------------------------------------------------------------------ template - inline void pod_deque::remove_last() + inline void pod_bvector::remove_last() { if(m_size) --m_size; } @@ -486,7 +668,7 @@ namespace agg //------------------------------------------------------------------------ template - void pod_deque::modify_last(const T& val) + void pod_bvector::modify_last(const T& val) { remove_last(); add(val); @@ -495,7 +677,7 @@ namespace agg //------------------------------------------------------------------------ template - int pod_deque::allocate_continuous_block(unsigned num_elements) + int pod_bvector::allocate_continuous_block(unsigned num_elements) { if(num_elements < block_size) { @@ -525,7 +707,7 @@ namespace agg //------------------------------------------------------------------------ template - unsigned pod_deque::byte_size() const + unsigned pod_bvector::byte_size() const { return m_size * sizeof(T); } @@ -533,7 +715,7 @@ namespace agg //------------------------------------------------------------------------ template - void pod_deque::serialize(int8u* ptr) const + void pod_bvector::serialize(int8u* ptr) const { unsigned i; for(i = 0; i < m_size; i++) @@ -545,7 +727,7 @@ namespace agg //------------------------------------------------------------------------ template - void pod_deque::deserialize(const int8u* data, unsigned byte_size) + void pod_bvector::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 - void pod_deque::deserialize(unsigned start, const T& empty_val, - const int8u* data, unsigned byte_size) + void pod_bvector::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::deallocate(blk->data, blk->size); --blk; } - delete [] m_blocks; + pod_allocator::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::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::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::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 @@ -849,9 +1044,76 @@ namespace agg return j; } + //--------------------------------------------------------invert_container + template 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 + 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 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 diff --git a/headers/libs/agg/agg_arrowhead.h b/headers/libs/agg/agg_arrowhead.h index 2c38608bfd..5e029ddee0 100644 --- a/headers/libs/agg/agg_arrowhead.h +++ b/headers/libs/agg/agg_arrowhead.h @@ -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: diff --git a/headers/libs/agg/agg_basics.h b/headers/libs/agg/agg_basics.h index 3c91a91d47..ad1e5c78c8 100644 --- a/headers/libs/agg/agg_basics.h +++ b/headers/libs/agg/agg_basics.h @@ -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 +#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 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 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 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 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< rect; //----rect + typedef rect_base rect_i; //----rect_i + typedef rect_base rect_f; //----rect_f typedef rect_base 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 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 point_i; //-----point_i + typedef point_base point_f; //-----point_f + typedef point_base point_d; //-----point_d - //-------------------------------------------------------------vertex_type - struct vertex_type + //-------------------------------------------------------------vertex_base + template 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 vertex_i; //-----vertex_i + typedef vertex_base vertex_f; //-----vertex_f + typedef vertex_base vertex_d; //-----vertex_d } diff --git a/headers/libs/agg/agg_bezier_arc.h b/headers/libs/agg/agg_bezier_arc.h index 588a326331..6d98d1a9f0 100644 --- a/headers/libs/agg/agg_bezier_arc.h +++ b/headers/libs/agg/agg_bezier_arc.h @@ -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; }; diff --git a/headers/libs/agg/agg_bitset_iterator.h b/headers/libs/agg/agg_bitset_iterator.h index 72643988f4..7382d5c335 100644 --- a/headers/libs/agg/agg_bitset_iterator.h +++ b/headers/libs/agg/agg_bitset_iterator.h @@ -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. diff --git a/headers/libs/agg/agg_blur.h b/headers/libs/agg/agg_blur.h new file mode 100644 index 0000000000..0860f52e19 --- /dev/null +++ b/headers/libs/agg/agg_blur.h @@ -0,0 +1,1294 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// The Stack Blur Algorithm was invented by Mario Klingemann, +// mario@quasimondo.com and described here: +// http://incubator.quasimondo.com/processing/fast_blur_deluxe.php +// (search phrase "Stackblur: Fast But Goodlooking"). +// The major improvement is that there's no more division table +// that was very expensive to create for large blur radii. Insted, +// for 8-bit per channel and radius not exceeding 254 the division is +// replaced by multiplication and shift. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_BLUR_INCLUDED +#define AGG_BLUR_INCLUDED + +#include "agg_array.h" +#include "agg_pixfmt_transposer.h" + +namespace agg +{ + + template struct stack_blur_tables + { + static int16u const g_stack_blur8_mul[255]; + static int8u const g_stack_blur8_shr[255]; + }; + + //------------------------------------------------------------------------ + template + int16u const stack_blur_tables::g_stack_blur8_mul[255] = + { + 512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512, + 454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512, + 482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456, + 437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512, + 497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328, + 320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456, + 446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335, + 329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512, + 505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405, + 399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328, + 324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271, + 268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456, + 451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388, + 385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335, + 332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292, + 289,287,285,282,280,278,275,273,271,269,267,265,263,261,259 + }; + + //------------------------------------------------------------------------ + template + int8u const stack_blur_tables::g_stack_blur8_shr[255] = + { + 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 + }; + + + + //==============================================================stack_blur + template class stack_blur + { + public: + typedef ColorT color_type; + typedef CalculatorT calculator_type; + + //-------------------------------------------------------------------- + template void blur_x(Img& img, unsigned radius) + { + if(radius < 1) return; + + unsigned x, y, xp, i; + unsigned stack_ptr; + unsigned stack_start; + + color_type pix; + color_type* stack_pix; + calculator_type sum; + calculator_type sum_in; + calculator_type sum_out; + + unsigned w = img.width(); + unsigned h = img.height(); + unsigned wm = w - 1; + unsigned div = radius * 2 + 1; + + unsigned div_sum = (radius + 1) * (radius + 1); + unsigned mul_sum = 0; + unsigned shr_sum = 0; + unsigned max_val = color_type::base_mask; + + if(max_val <= 255 && radius < 255) + { + mul_sum = stack_blur_tables::g_stack_blur8_mul[radius]; + shr_sum = stack_blur_tables::g_stack_blur8_shr[radius]; + } + + m_buf.allocate(w, 128); + m_stack.allocate(div, 32); + + for(y = 0; y < h; y++) + { + sum.clear(); + sum_in.clear(); + sum_out.clear(); + + pix = img.pixel(0, y); + for(i = 0; i <= radius; i++) + { + m_stack[i] = pix; + sum.add(pix, i + 1); + sum_out.add(pix); + } + for(i = 1; i <= radius; i++) + { + pix = img.pixel((i > wm) ? wm : i, y); + m_stack[i + radius] = pix; + sum.add(pix, radius + 1 - i); + sum_in.add(pix); + } + + stack_ptr = radius; + for(x = 0; x < w; x++) + { + if(mul_sum) sum.calc_pix(m_buf[x], mul_sum, shr_sum); + else sum.calc_pix(m_buf[x], div_sum); + + sum.sub(sum_out); + + stack_start = stack_ptr + div - radius; + if(stack_start >= div) stack_start -= div; + stack_pix = &m_stack[stack_start]; + + sum_out.sub(*stack_pix); + + xp = x + radius + 1; + if(xp > wm) xp = wm; + pix = img.pixel(xp, y); + + *stack_pix = pix; + + sum_in.add(pix); + sum.add(sum_in); + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix = &m_stack[stack_ptr]; + + sum_out.add(*stack_pix); + sum_in.sub(*stack_pix); + } + img.copy_color_hspan(0, y, w, &m_buf[0]); + } + } + + //-------------------------------------------------------------------- + template void blur_y(Img& img, unsigned radius) + { + pixfmt_transposer img2(img); + blur_x(img2, radius); + } + + //-------------------------------------------------------------------- + template void blur(Img& img, unsigned radius) + { + blur_x(img, radius); + pixfmt_transposer img2(img); + blur_x(img2, radius); + } + + private: + pod_vector m_buf; + pod_vector m_stack; + }; + + //====================================================stack_blur_calc_rgba + template struct stack_blur_calc_rgba + { + typedef T value_type; + value_type r,g,b,a; + + AGG_INLINE void clear() + { + r = g = b = a = 0; + } + + template AGG_INLINE void add(const ArgT& v) + { + r += v.r; + g += v.g; + b += v.b; + a += v.a; + } + + template AGG_INLINE void add(const ArgT& v, unsigned k) + { + r += v.r * k; + g += v.g * k; + b += v.b * k; + a += v.a * k; + } + + template AGG_INLINE void sub(const ArgT& v) + { + r -= v.r; + g -= v.g; + b -= v.b; + a -= v.a; + } + + template AGG_INLINE void calc_pix(ArgT& v, unsigned div) + { + typedef typename ArgT::value_type value_type; + v.r = value_type(r / div); + v.g = value_type(g / div); + v.b = value_type(b / div); + v.a = value_type(a / div); + } + + template + AGG_INLINE void calc_pix(ArgT& v, unsigned mul, unsigned shr) + { + typedef typename ArgT::value_type value_type; + v.r = value_type((r * mul) >> shr); + v.g = value_type((g * mul) >> shr); + v.b = value_type((b * mul) >> shr); + v.a = value_type((a * mul) >> shr); + } + }; + + + //=====================================================stack_blur_calc_rgb + template struct stack_blur_calc_rgb + { + typedef T value_type; + value_type r,g,b; + + AGG_INLINE void clear() + { + r = g = b = 0; + } + + template AGG_INLINE void add(const ArgT& v) + { + r += v.r; + g += v.g; + b += v.b; + } + + template AGG_INLINE void add(const ArgT& v, unsigned k) + { + r += v.r * k; + g += v.g * k; + b += v.b * k; + } + + template AGG_INLINE void sub(const ArgT& v) + { + r -= v.r; + g -= v.g; + b -= v.b; + } + + template AGG_INLINE void calc_pix(ArgT& v, unsigned div) + { + typedef typename ArgT::value_type value_type; + v.r = value_type(r / div); + v.g = value_type(g / div); + v.b = value_type(b / div); + } + + template + AGG_INLINE void calc_pix(ArgT& v, unsigned mul, unsigned shr) + { + typedef typename ArgT::value_type value_type; + v.r = value_type((r * mul) >> shr); + v.g = value_type((g * mul) >> shr); + v.b = value_type((b * mul) >> shr); + } + }; + + + //====================================================stack_blur_calc_gray + template struct stack_blur_calc_gray + { + typedef T value_type; + value_type v; + + AGG_INLINE void clear() + { + v = 0; + } + + template AGG_INLINE void add(const ArgT& a) + { + v += a.v; + } + + template AGG_INLINE void add(const ArgT& a, unsigned k) + { + v += a.v * k; + } + + template AGG_INLINE void sub(const ArgT& a) + { + v -= a.v; + } + + template AGG_INLINE void calc_pix(ArgT& a, unsigned div) + { + typedef typename ArgT::value_type value_type; + a.v = value_type(v / div); + } + + template + AGG_INLINE void calc_pix(ArgT& a, unsigned mul, unsigned shr) + { + typedef typename ArgT::value_type value_type; + a.v = value_type((v * mul) >> shr); + } + }; + + + + //========================================================stack_blur_gray8 + template + void stack_blur_gray8(Img& img, unsigned rx, unsigned ry) + { + unsigned x, y, xp, yp, i; + unsigned stack_ptr; + unsigned stack_start; + + const int8u* src_pix_ptr; + int8u* dst_pix_ptr; + unsigned pix; + unsigned stack_pix; + unsigned sum; + unsigned sum_in; + unsigned sum_out; + + unsigned w = img.width(); + unsigned h = img.height(); + unsigned wm = w - 1; + unsigned hm = h - 1; + + unsigned div; + unsigned mul_sum; + unsigned shr_sum; + + pod_vector stack; + + if(rx > 0) + { + if(rx > 254) rx = 254; + div = rx * 2 + 1; + mul_sum = stack_blur_tables::g_stack_blur8_mul[rx]; + shr_sum = stack_blur_tables::g_stack_blur8_shr[rx]; + stack.allocate(div); + + for(y = 0; y < h; y++) + { + sum = sum_in = sum_out = 0; + + src_pix_ptr = img.pix_ptr(0, y); + pix = *src_pix_ptr; + for(i = 0; i <= rx; i++) + { + stack[i] = pix; + sum += pix * (i + 1); + sum_out += pix; + } + for(i = 1; i <= rx; i++) + { + if(i <= wm) src_pix_ptr += Img::pix_step; + pix = *src_pix_ptr; + stack[i + rx] = pix; + sum += pix * (rx + 1 - i); + sum_in += pix; + } + + stack_ptr = rx; + xp = rx; + if(xp > wm) xp = wm; + src_pix_ptr = img.pix_ptr(xp, y); + dst_pix_ptr = img.pix_ptr(0, y); + for(x = 0; x < w; x++) + { + *dst_pix_ptr = (sum * mul_sum) >> shr_sum; + dst_pix_ptr += Img::pix_step; + + sum -= sum_out; + + stack_start = stack_ptr + div - rx; + if(stack_start >= div) stack_start -= div; + sum_out -= stack[stack_start]; + + if(xp < wm) + { + src_pix_ptr += Img::pix_step; + pix = *src_pix_ptr; + ++xp; + } + + stack[stack_start] = pix; + + sum_in += pix; + sum += sum_in; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix = stack[stack_ptr]; + + sum_out += stack_pix; + sum_in -= stack_pix; + } + } + } + + if(ry > 0) + { + if(ry > 254) ry = 254; + div = ry * 2 + 1; + mul_sum = stack_blur_tables::g_stack_blur8_mul[ry]; + shr_sum = stack_blur_tables::g_stack_blur8_shr[ry]; + stack.allocate(div); + + int stride = img.stride(); + for(x = 0; x < w; x++) + { + sum = sum_in = sum_out = 0; + + src_pix_ptr = img.pix_ptr(x, 0); + pix = *src_pix_ptr; + for(i = 0; i <= ry; i++) + { + stack[i] = pix; + sum += pix * (i + 1); + sum_out += pix; + } + for(i = 1; i <= ry; i++) + { + if(i <= hm) src_pix_ptr += stride; + pix = *src_pix_ptr; + stack[i + ry] = pix; + sum += pix * (ry + 1 - i); + sum_in += pix; + } + + stack_ptr = ry; + yp = ry; + if(yp > hm) yp = hm; + src_pix_ptr = img.pix_ptr(x, yp); + dst_pix_ptr = img.pix_ptr(x, 0); + for(y = 0; y < h; y++) + { + *dst_pix_ptr = (sum * mul_sum) >> shr_sum; + dst_pix_ptr += stride; + + sum -= sum_out; + + stack_start = stack_ptr + div - ry; + if(stack_start >= div) stack_start -= div; + sum_out -= stack[stack_start]; + + if(yp < hm) + { + src_pix_ptr += stride; + pix = *src_pix_ptr; + ++yp; + } + + stack[stack_start] = pix; + + sum_in += pix; + sum += sum_in; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix = stack[stack_ptr]; + + sum_out += stack_pix; + sum_in -= stack_pix; + } + } + } + } + + + + //========================================================stack_blur_rgb24 + template + void stack_blur_rgb24(Img& img, unsigned rx, unsigned ry) + { + typedef typename Img::color_type color_type; + typedef typename Img::order_type order_type; + enum order_e + { + R = order_type::R, + G = order_type::G, + B = order_type::B + }; + + unsigned x, y, xp, yp, i; + unsigned stack_ptr; + unsigned stack_start; + + const int8u* src_pix_ptr; + int8u* dst_pix_ptr; + color_type* stack_pix_ptr; + + unsigned sum_r; + unsigned sum_g; + unsigned sum_b; + unsigned sum_in_r; + unsigned sum_in_g; + unsigned sum_in_b; + unsigned sum_out_r; + unsigned sum_out_g; + unsigned sum_out_b; + + unsigned w = img.width(); + unsigned h = img.height(); + unsigned wm = w - 1; + unsigned hm = h - 1; + + unsigned div; + unsigned mul_sum; + unsigned shr_sum; + + pod_vector stack; + + if(rx > 0) + { + if(rx > 254) rx = 254; + div = rx * 2 + 1; + mul_sum = stack_blur_tables::g_stack_blur8_mul[rx]; + shr_sum = stack_blur_tables::g_stack_blur8_shr[rx]; + stack.allocate(div); + + for(y = 0; y < h; y++) + { + sum_r = + sum_g = + sum_b = + sum_in_r = + sum_in_g = + sum_in_b = + sum_out_r = + sum_out_g = + sum_out_b = 0; + + src_pix_ptr = img.pix_ptr(0, y); + for(i = 0; i <= rx; i++) + { + stack_pix_ptr = &stack[i]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + sum_r += src_pix_ptr[R] * (i + 1); + sum_g += src_pix_ptr[G] * (i + 1); + sum_b += src_pix_ptr[B] * (i + 1); + sum_out_r += src_pix_ptr[R]; + sum_out_g += src_pix_ptr[G]; + sum_out_b += src_pix_ptr[B]; + } + for(i = 1; i <= rx; i++) + { + if(i <= wm) src_pix_ptr += Img::pix_width; + stack_pix_ptr = &stack[i + rx]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + sum_r += src_pix_ptr[R] * (rx + 1 - i); + sum_g += src_pix_ptr[G] * (rx + 1 - i); + sum_b += src_pix_ptr[B] * (rx + 1 - i); + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + } + + stack_ptr = rx; + xp = rx; + if(xp > wm) xp = wm; + src_pix_ptr = img.pix_ptr(xp, y); + dst_pix_ptr = img.pix_ptr(0, y); + for(x = 0; x < w; x++) + { + dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; + dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; + dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; + dst_pix_ptr += Img::pix_width; + + sum_r -= sum_out_r; + sum_g -= sum_out_g; + sum_b -= sum_out_b; + + stack_start = stack_ptr + div - rx; + if(stack_start >= div) stack_start -= div; + stack_pix_ptr = &stack[stack_start]; + + sum_out_r -= stack_pix_ptr->r; + sum_out_g -= stack_pix_ptr->g; + sum_out_b -= stack_pix_ptr->b; + + if(xp < wm) + { + src_pix_ptr += Img::pix_width; + ++xp; + } + + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_r += sum_in_r; + sum_g += sum_in_g; + sum_b += sum_in_b; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix_ptr = &stack[stack_ptr]; + + sum_out_r += stack_pix_ptr->r; + sum_out_g += stack_pix_ptr->g; + sum_out_b += stack_pix_ptr->b; + sum_in_r -= stack_pix_ptr->r; + sum_in_g -= stack_pix_ptr->g; + sum_in_b -= stack_pix_ptr->b; + } + } + } + + if(ry > 0) + { + if(ry > 254) ry = 254; + div = ry * 2 + 1; + mul_sum = stack_blur_tables::g_stack_blur8_mul[ry]; + shr_sum = stack_blur_tables::g_stack_blur8_shr[ry]; + stack.allocate(div); + + int stride = img.stride(); + for(x = 0; x < w; x++) + { + sum_r = + sum_g = + sum_b = + sum_in_r = + sum_in_g = + sum_in_b = + sum_out_r = + sum_out_g = + sum_out_b = 0; + + src_pix_ptr = img.pix_ptr(x, 0); + for(i = 0; i <= ry; i++) + { + stack_pix_ptr = &stack[i]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + sum_r += src_pix_ptr[R] * (i + 1); + sum_g += src_pix_ptr[G] * (i + 1); + sum_b += src_pix_ptr[B] * (i + 1); + sum_out_r += src_pix_ptr[R]; + sum_out_g += src_pix_ptr[G]; + sum_out_b += src_pix_ptr[B]; + } + for(i = 1; i <= ry; i++) + { + if(i <= hm) src_pix_ptr += stride; + stack_pix_ptr = &stack[i + ry]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + sum_r += src_pix_ptr[R] * (ry + 1 - i); + sum_g += src_pix_ptr[G] * (ry + 1 - i); + sum_b += src_pix_ptr[B] * (ry + 1 - i); + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + } + + stack_ptr = ry; + yp = ry; + if(yp > hm) yp = hm; + src_pix_ptr = img.pix_ptr(x, yp); + dst_pix_ptr = img.pix_ptr(x, 0); + for(y = 0; y < h; y++) + { + dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; + dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; + dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; + dst_pix_ptr += stride; + + sum_r -= sum_out_r; + sum_g -= sum_out_g; + sum_b -= sum_out_b; + + stack_start = stack_ptr + div - ry; + if(stack_start >= div) stack_start -= div; + + stack_pix_ptr = &stack[stack_start]; + sum_out_r -= stack_pix_ptr->r; + sum_out_g -= stack_pix_ptr->g; + sum_out_b -= stack_pix_ptr->b; + + if(yp < hm) + { + src_pix_ptr += stride; + ++yp; + } + + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_r += sum_in_r; + sum_g += sum_in_g; + sum_b += sum_in_b; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix_ptr = &stack[stack_ptr]; + + sum_out_r += stack_pix_ptr->r; + sum_out_g += stack_pix_ptr->g; + sum_out_b += stack_pix_ptr->b; + sum_in_r -= stack_pix_ptr->r; + sum_in_g -= stack_pix_ptr->g; + sum_in_b -= stack_pix_ptr->b; + } + } + } + } + + + + //=======================================================stack_blur_rgba32 + template + void stack_blur_rgba32(Img& img, unsigned rx, unsigned ry) + { + typedef typename Img::color_type color_type; + typedef typename Img::order_type order_type; + enum order_e + { + R = order_type::R, + G = order_type::G, + B = order_type::B, + A = order_type::A + }; + + unsigned x, y, xp, yp, i; + unsigned stack_ptr; + unsigned stack_start; + + const int8u* src_pix_ptr; + int8u* dst_pix_ptr; + color_type* stack_pix_ptr; + + unsigned sum_r; + unsigned sum_g; + unsigned sum_b; + unsigned sum_a; + unsigned sum_in_r; + unsigned sum_in_g; + unsigned sum_in_b; + unsigned sum_in_a; + unsigned sum_out_r; + unsigned sum_out_g; + unsigned sum_out_b; + unsigned sum_out_a; + + unsigned w = img.width(); + unsigned h = img.height(); + unsigned wm = w - 1; + unsigned hm = h - 1; + + unsigned div; + unsigned mul_sum; + unsigned shr_sum; + + pod_vector stack; + + if(rx > 0) + { + if(rx > 254) rx = 254; + div = rx * 2 + 1; + mul_sum = stack_blur_tables::g_stack_blur8_mul[rx]; + shr_sum = stack_blur_tables::g_stack_blur8_shr[rx]; + stack.allocate(div); + + for(y = 0; y < h; y++) + { + sum_r = + sum_g = + sum_b = + sum_a = + sum_in_r = + sum_in_g = + sum_in_b = + sum_in_a = + sum_out_r = + sum_out_g = + sum_out_b = + sum_out_a = 0; + + src_pix_ptr = img.pix_ptr(0, y); + for(i = 0; i <= rx; i++) + { + stack_pix_ptr = &stack[i]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + sum_r += src_pix_ptr[R] * (i + 1); + sum_g += src_pix_ptr[G] * (i + 1); + sum_b += src_pix_ptr[B] * (i + 1); + sum_a += src_pix_ptr[A] * (i + 1); + sum_out_r += src_pix_ptr[R]; + sum_out_g += src_pix_ptr[G]; + sum_out_b += src_pix_ptr[B]; + sum_out_a += src_pix_ptr[A]; + } + for(i = 1; i <= rx; i++) + { + if(i <= wm) src_pix_ptr += Img::pix_width; + stack_pix_ptr = &stack[i + rx]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + sum_r += src_pix_ptr[R] * (rx + 1 - i); + sum_g += src_pix_ptr[G] * (rx + 1 - i); + sum_b += src_pix_ptr[B] * (rx + 1 - i); + sum_a += src_pix_ptr[A] * (rx + 1 - i); + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_in_a += src_pix_ptr[A]; + } + + stack_ptr = rx; + xp = rx; + if(xp > wm) xp = wm; + src_pix_ptr = img.pix_ptr(xp, y); + dst_pix_ptr = img.pix_ptr(0, y); + for(x = 0; x < w; x++) + { + dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; + dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; + dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; + dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum; + dst_pix_ptr += Img::pix_width; + + sum_r -= sum_out_r; + sum_g -= sum_out_g; + sum_b -= sum_out_b; + sum_a -= sum_out_a; + + stack_start = stack_ptr + div - rx; + if(stack_start >= div) stack_start -= div; + stack_pix_ptr = &stack[stack_start]; + + sum_out_r -= stack_pix_ptr->r; + sum_out_g -= stack_pix_ptr->g; + sum_out_b -= stack_pix_ptr->b; + sum_out_a -= stack_pix_ptr->a; + + if(xp < wm) + { + src_pix_ptr += Img::pix_width; + ++xp; + } + + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_in_a += src_pix_ptr[A]; + sum_r += sum_in_r; + sum_g += sum_in_g; + sum_b += sum_in_b; + sum_a += sum_in_a; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix_ptr = &stack[stack_ptr]; + + sum_out_r += stack_pix_ptr->r; + sum_out_g += stack_pix_ptr->g; + sum_out_b += stack_pix_ptr->b; + sum_out_a += stack_pix_ptr->a; + sum_in_r -= stack_pix_ptr->r; + sum_in_g -= stack_pix_ptr->g; + sum_in_b -= stack_pix_ptr->b; + sum_in_a -= stack_pix_ptr->a; + } + } + } + + if(ry > 0) + { + if(ry > 254) ry = 254; + div = ry * 2 + 1; + mul_sum = stack_blur_tables::g_stack_blur8_mul[ry]; + shr_sum = stack_blur_tables::g_stack_blur8_shr[ry]; + stack.allocate(div); + + int stride = img.stride(); + for(x = 0; x < w; x++) + { + sum_r = + sum_g = + sum_b = + sum_a = + sum_in_r = + sum_in_g = + sum_in_b = + sum_in_a = + sum_out_r = + sum_out_g = + sum_out_b = + sum_out_a = 0; + + src_pix_ptr = img.pix_ptr(x, 0); + for(i = 0; i <= ry; i++) + { + stack_pix_ptr = &stack[i]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + sum_r += src_pix_ptr[R] * (i + 1); + sum_g += src_pix_ptr[G] * (i + 1); + sum_b += src_pix_ptr[B] * (i + 1); + sum_a += src_pix_ptr[A] * (i + 1); + sum_out_r += src_pix_ptr[R]; + sum_out_g += src_pix_ptr[G]; + sum_out_b += src_pix_ptr[B]; + sum_out_a += src_pix_ptr[A]; + } + for(i = 1; i <= ry; i++) + { + if(i <= hm) src_pix_ptr += stride; + stack_pix_ptr = &stack[i + ry]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + sum_r += src_pix_ptr[R] * (ry + 1 - i); + sum_g += src_pix_ptr[G] * (ry + 1 - i); + sum_b += src_pix_ptr[B] * (ry + 1 - i); + sum_a += src_pix_ptr[A] * (ry + 1 - i); + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_in_a += src_pix_ptr[A]; + } + + stack_ptr = ry; + yp = ry; + if(yp > hm) yp = hm; + src_pix_ptr = img.pix_ptr(x, yp); + dst_pix_ptr = img.pix_ptr(x, 0); + for(y = 0; y < h; y++) + { + dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; + dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; + dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; + dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum; + dst_pix_ptr += stride; + + sum_r -= sum_out_r; + sum_g -= sum_out_g; + sum_b -= sum_out_b; + sum_a -= sum_out_a; + + stack_start = stack_ptr + div - ry; + if(stack_start >= div) stack_start -= div; + + stack_pix_ptr = &stack[stack_start]; + sum_out_r -= stack_pix_ptr->r; + sum_out_g -= stack_pix_ptr->g; + sum_out_b -= stack_pix_ptr->b; + sum_out_a -= stack_pix_ptr->a; + + if(yp < hm) + { + src_pix_ptr += stride; + ++yp; + } + + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_in_a += src_pix_ptr[A]; + sum_r += sum_in_r; + sum_g += sum_in_g; + sum_b += sum_in_b; + sum_a += sum_in_a; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix_ptr = &stack[stack_ptr]; + + sum_out_r += stack_pix_ptr->r; + sum_out_g += stack_pix_ptr->g; + sum_out_b += stack_pix_ptr->b; + sum_out_a += stack_pix_ptr->a; + sum_in_r -= stack_pix_ptr->r; + sum_in_g -= stack_pix_ptr->g; + sum_in_b -= stack_pix_ptr->b; + sum_in_a -= stack_pix_ptr->a; + } + } + } + } + + + + //===========================================================recursive_blur + template class recursive_blur + { + public: + typedef ColorT color_type; + typedef CalculatorT calculator_type; + typedef typename color_type::value_type value_type; + typedef typename calculator_type::value_type calc_type; + + //-------------------------------------------------------------------- + template void blur_x(Img& img, double radius) + { + if(radius < 0.62) return; + if(img.width() < 3) return; + + calc_type s = calc_type(radius * 0.5); + calc_type q = calc_type((s < 2.5) ? + 3.97156 - 4.14554 * sqrt(1 - 0.26891 * s) : + 0.98711 * s - 0.96330); + + calc_type q2 = calc_type(q * q); + calc_type q3 = calc_type(q2 * q); + + calc_type b0 = calc_type(1.0 / (1.578250 + + 2.444130 * q + + 1.428100 * q2 + + 0.422205 * q3)); + + calc_type b1 = calc_type( 2.44413 * q + + 2.85619 * q2 + + 1.26661 * q3); + + calc_type b2 = calc_type(-1.42810 * q2 + + -1.26661 * q3); + + calc_type b3 = calc_type(0.422205 * q3); + + calc_type b = calc_type(1 - (b1 + b2 + b3) * b0); + + b1 *= b0; + b2 *= b0; + b3 *= b0; + + int w = img.width(); + int h = img.height(); + int wm = w-1; + int x, y; + + m_sum1.allocate(w); + m_sum2.allocate(w); + m_buf.allocate(w); + + for(y = 0; y < h; y++) + { + calculator_type c; + c.from_pix(img.pixel(0, y)); + m_sum1[0].calc(b, b1, b2, b3, c, c, c, c); + c.from_pix(img.pixel(1, y)); + m_sum1[1].calc(b, b1, b2, b3, c, m_sum1[0], m_sum1[0], m_sum1[0]); + c.from_pix(img.pixel(2, y)); + m_sum1[2].calc(b, b1, b2, b3, c, m_sum1[1], m_sum1[0], m_sum1[0]); + + for(x = 3; x < w; ++x) + { + c.from_pix(img.pixel(x, y)); + m_sum1[x].calc(b, b1, b2, b3, c, m_sum1[x-1], m_sum1[x-2], m_sum1[x-3]); + } + + m_sum2[wm ].calc(b, b1, b2, b3, m_sum1[wm ], m_sum1[wm ], m_sum1[wm], m_sum1[wm]); + m_sum2[wm-1].calc(b, b1, b2, b3, m_sum1[wm-1], m_sum2[wm ], m_sum2[wm], m_sum2[wm]); + m_sum2[wm-2].calc(b, b1, b2, b3, m_sum1[wm-2], m_sum2[wm-1], m_sum2[wm], m_sum2[wm]); + m_sum2[wm ].to_pix(m_buf[wm ]); + m_sum2[wm-1].to_pix(m_buf[wm-1]); + m_sum2[wm-2].to_pix(m_buf[wm-2]); + + for(x = wm-3; x >= 0; --x) + { + m_sum2[x].calc(b, b1, b2, b3, m_sum1[x], m_sum2[x+1], m_sum2[x+2], m_sum2[x+3]); + m_sum2[x].to_pix(m_buf[x]); + } + img.copy_color_hspan(0, y, w, &m_buf[0]); + } + } + + //-------------------------------------------------------------------- + template void blur_y(Img& img, double radius) + { + pixfmt_transposer img2(img); + blur_x(img2, radius); + } + + //-------------------------------------------------------------------- + template void blur(Img& img, double radius) + { + blur_x(img, radius); + pixfmt_transposer img2(img); + blur_x(img2, radius); + } + + private: + agg::pod_vector m_sum1; + agg::pod_vector m_sum2; + agg::pod_vector m_buf; + }; + + + //=================================================recursive_blur_calc_rgba + template struct recursive_blur_calc_rgba + { + typedef T value_type; + typedef recursive_blur_calc_rgba self_type; + + value_type r,g,b,a; + + template + AGG_INLINE void from_pix(const ColorT& c) + { + r = c.r; + g = c.g; + b = c.b; + a = c.a; + } + + AGG_INLINE void calc(value_type b1, + value_type b2, + value_type b3, + value_type b4, + const self_type& c1, + const self_type& c2, + const self_type& c3, + const self_type& c4) + { + r = b1*c1.r + b2*c2.r + b3*c3.r + b4*c4.r; + g = b1*c1.g + b2*c2.g + b3*c3.g + b4*c4.g; + b = b1*c1.b + b2*c2.b + b3*c3.b + b4*c4.b; + a = b1*c1.a + b2*c2.a + b3*c3.a + b4*c4.a; + } + + template + AGG_INLINE void to_pix(ColorT& c) const + { + typedef typename ColorT::value_type cv_type; + c.r = (cv_type)uround(r); + c.g = (cv_type)uround(g); + c.b = (cv_type)uround(b); + c.a = (cv_type)uround(a); + } + }; + + + //=================================================recursive_blur_calc_rgb + template struct recursive_blur_calc_rgb + { + typedef T value_type; + typedef recursive_blur_calc_rgb self_type; + + value_type r,g,b; + + template + AGG_INLINE void from_pix(const ColorT& c) + { + r = c.r; + g = c.g; + b = c.b; + } + + AGG_INLINE void calc(value_type b1, + value_type b2, + value_type b3, + value_type b4, + const self_type& c1, + const self_type& c2, + const self_type& c3, + const self_type& c4) + { + r = b1*c1.r + b2*c2.r + b3*c3.r + b4*c4.r; + g = b1*c1.g + b2*c2.g + b3*c3.g + b4*c4.g; + b = b1*c1.b + b2*c2.b + b3*c3.b + b4*c4.b; + } + + template + AGG_INLINE void to_pix(ColorT& c) const + { + typedef typename ColorT::value_type cv_type; + c.r = (cv_type)uround(r); + c.g = (cv_type)uround(g); + c.b = (cv_type)uround(b); + } + }; + + + //================================================recursive_blur_calc_gray + template struct recursive_blur_calc_gray + { + typedef T value_type; + typedef recursive_blur_calc_gray self_type; + + value_type v; + + template + AGG_INLINE void from_pix(const ColorT& c) + { + v = c.v; + } + + AGG_INLINE void calc(value_type b1, + value_type b2, + value_type b3, + value_type b4, + const self_type& c1, + const self_type& c2, + const self_type& c3, + const self_type& c4) + { + v = b1*c1.v + b2*c2.v + b3*c3.v + b4*c4.v; + } + + template + AGG_INLINE void to_pix(ColorT& c) const + { + typedef typename ColorT::value_type cv_type; + c.v = (cv_type)uround(v); + } + }; + +} + + + + +#endif diff --git a/headers/libs/agg/agg_bounding_rect.h b/headers/libs/agg/agg_bounding_rect.h index 58072fec9c..f13b863f0f 100644 --- a/headers/libs/agg/agg_bounding_rect.h +++ b/headers/libs/agg/agg_bounding_rect.h @@ -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. diff --git a/headers/libs/agg/agg_bspline.h b/headers/libs/agg/agg_bspline.h index 1ccdefbfec..2c1ed9a38c 100644 --- a/headers/libs/agg/agg_bspline.h +++ b/headers/libs/agg/agg_bspline.h @@ -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 m_am; + mutable int m_last_idx; }; diff --git a/headers/libs/agg/agg_clip_liang_barsky.h b/headers/libs/agg/agg_clip_liang_barsky.h index d3a47b493f..4b5fedbab5 100644 --- a/headers/libs/agg/agg_clip_liang_barsky.h +++ b/headers/libs/agg/agg_clip_liang_barsky.h @@ -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 + inline unsigned clipping_flags_x(T x, const rect_base& clip_box) + { + return (x > clip_box.x2) | ((x < clip_box.x1) << 2); + } + + + //--------------------------------------------------------clipping_flags_y + template + inline unsigned clipping_flags_y(T y, const rect_base& 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 + bool clip_move_point(T x1, T y1, T x2, T y2, + const rect_base& 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 + unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2, + const rect_base& 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 diff --git a/headers/libs/agg/agg_color_gray.h b/headers/libs/agg/agg_color_gray.h new file mode 100644 index 0000000000..461a4990aa --- /dev/null +++ b/headers/libs/agg/agg_color_gray.h @@ -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: mcseem@antigrain.com +// mcseemagg@yahoo.com +// 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 diff --git a/headers/libs/agg/agg_color_rgba.h b/headers/libs/agg/agg_color_rgba.h index d826dc917d..befa1650fa 100644 --- a/headers/libs/agg/agg_color_rgba.h +++ b/headers/libs/agg/agg_color_rgba.h @@ -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: mcseem@antigrain.com // mcseemagg@yahoo.com // 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 + AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) + { + r = gamma.dir(r); + g = gamma.dir(g); + b = gamma.dir(b); + } + + //-------------------------------------------------------------------- + template + 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 + AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) + { + r = gamma.dir(r); + g = gamma.dir(g); + b = gamma.dir(b); + } + + //-------------------------------------------------------------------- + template + 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 diff --git a/headers/libs/agg/agg_color_rgba8.h b/headers/libs/agg/agg_color_rgba8.h deleted file mode 100644 index 6790b8a095..0000000000 --- a/headers/libs/agg/agg_color_rgba8.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// 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 diff --git a/headers/libs/agg/agg_config.h b/headers/libs/agg/agg_config.h new file mode 100644 index 0000000000..32bf946f54 --- /dev/null +++ b/headers/libs/agg/agg_config.h @@ -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 diff --git a/headers/libs/agg/agg_conv_adaptor_vcgen.h b/headers/libs/agg/agg_conv_adaptor_vcgen.h index cf5392956a..cee24b271d 100755 --- a/headers/libs/agg/agg_conv_adaptor_vcgen.h +++ b/headers/libs/agg/agg_conv_adaptor_vcgen.h @@ -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 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 source_type; - typedef vertex_iterator 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&); diff --git a/headers/libs/agg/agg_conv_adaptor_vpgen.h b/headers/libs/agg/agg_conv_adaptor_vpgen.h index a258096de7..8fcedcbef0 100755 --- a/headers/libs/agg/agg_conv_adaptor_vpgen.h +++ b/headers/libs/agg/agg_conv_adaptor_vpgen.h @@ -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 source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: conv_adaptor_vpgen(const conv_adaptor_vpgen&); const conv_adaptor_vpgen& diff --git a/headers/libs/agg/agg_conv_bspline.h b/headers/libs/agg/agg_conv_bspline.h index 6fcc1475c7..13d22d9297 100644 --- a/headers/libs/agg/agg_conv_bspline.h +++ b/headers/libs/agg/agg_conv_bspline.h @@ -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. diff --git a/headers/libs/agg/agg_conv_clip_polygon.h b/headers/libs/agg/agg_conv_clip_polygon.h index bc7d89728c..87537638dc 100644 --- a/headers/libs/agg/agg_conv_clip_polygon.h +++ b/headers/libs/agg/agg_conv_clip_polygon.h @@ -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 source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: conv_clip_polygon(const conv_clip_polygon&); const conv_clip_polygon& diff --git a/headers/libs/agg/agg_conv_clip_polyline.h b/headers/libs/agg/agg_conv_clip_polyline.h index 96115335e3..f3fc2888c2 100644 --- a/headers/libs/agg/agg_conv_clip_polyline.h +++ b/headers/libs/agg/agg_conv_clip_polyline.h @@ -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 source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: conv_clip_polyline(const conv_clip_polyline&); const conv_clip_polyline& diff --git a/headers/libs/agg/agg_conv_close_polygon.h b/headers/libs/agg/agg_conv_close_polygon.h index 038e778df5..7eecc9caf0 100644 --- a/headers/libs/agg/agg_conv_close_polygon.h +++ b/headers/libs/agg/agg_conv_close_polygon.h @@ -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 source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: conv_close_polygon(const conv_close_polygon&); const conv_close_polygon& diff --git a/headers/libs/agg/agg_conv_concat.h b/headers/libs/agg/agg_conv_concat.h index dcd5a5fcad..745d349c6f 100644 --- a/headers/libs/agg/agg_conv_concat.h +++ b/headers/libs/agg/agg_conv_concat.h @@ -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 source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: conv_concat(const conv_concat&); const conv_concat& diff --git a/headers/libs/agg/agg_conv_contour.h b/headers/libs/agg/agg_conv_contour.h index 76091caf89..b4b5a9047e 100644 --- a/headers/libs/agg/agg_conv_contour.h +++ b/headers/libs/agg/agg_conv_contour.h @@ -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(); } diff --git a/headers/libs/agg/agg_conv_curve.h b/headers/libs/agg/agg_conv_curve.h index fa51ca826a..8c5d397cff 100644 --- a/headers/libs/agg/agg_conv_curve.h +++ b/headers/libs/agg/agg_conv_curve.h @@ -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 conv_curve + template class conv_curve { public: + typedef Curve3 curve3_type; + typedef Curve4 curve4_type; + typedef conv_curve 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 source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: - conv_curve(const conv_curve&); - const conv_curve& - operator = (const conv_curve&); + 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 - void conv_curve::rewind(unsigned id) + template + void conv_curve::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 - unsigned conv_curve::vertex(double* x, double* y) + template + unsigned conv_curve::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; } diff --git a/headers/libs/agg/agg_conv_dash.h b/headers/libs/agg/agg_conv_dash.h index 6d5723b4fd..23c13ad0ab 100644 --- a/headers/libs/agg/agg_conv_dash.h +++ b/headers/libs/agg/agg_conv_dash.h @@ -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. diff --git a/headers/libs/agg/agg_conv_gpc.h b/headers/libs/agg/agg_conv_gpc.h index d303b9ed5d..2acada342d 100644 --- a/headers/libs/agg/agg_conv_gpc.h +++ b/headers/libs/agg/agg_conv_gpc.h @@ -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 #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 vertex_array_type; - typedef pod_deque contour_header_array_type; + typedef pod_bvector vertex_array_type; + typedef pod_bvector 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 iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: conv_gpc(const conv_gpc&); const conv_gpc& operator = (const conv_gpc&); @@ -197,10 +191,10 @@ namespace agg int i; for(i = 0; i < p.num_contours; i++) { - delete [] p.contour[i].vertex; + pod_allocator::deallocate(p.contour[i].vertex, + p.contour[i].num_vertices); } - delete [] p.hole; - delete [] p.contour; + pod_allocator::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::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::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 - void conv_gpc::rewind(unsigned id) + void conv_gpc::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) diff --git a/headers/libs/agg/agg_conv_marker.h b/headers/libs/agg/agg_conv_marker.h index fc84efe94c..2cd3cb403f 100644 --- a/headers/libs/agg/agg_conv_marker.h +++ b/headers/libs/agg/agg_conv_marker.h @@ -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 source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: conv_marker(const conv_marker&); const conv_marker& diff --git a/headers/libs/agg/agg_conv_marker_adaptor.h b/headers/libs/agg/agg_conv_marker_adaptor.h index d38b5e6c63..4486d6ace9 100644 --- a/headers/libs/agg/agg_conv_marker_adaptor.h +++ b/headers/libs/agg/agg_conv_marker_adaptor.h @@ -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. diff --git a/headers/libs/agg/agg_conv_segmentator.h b/headers/libs/agg/agg_conv_segmentator.h index 2c1cb6d884..e69a9e7d7d 100755 --- a/headers/libs/agg/agg_conv_segmentator.h +++ b/headers/libs/agg/agg_conv_segmentator.h @@ -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. diff --git a/headers/libs/agg/agg_conv_shorten_path.h b/headers/libs/agg/agg_conv_shorten_path.h index ed179ae5df..5617e51d17 100644 --- a/headers/libs/agg/agg_conv_shorten_path.h +++ b/headers/libs/agg/agg_conv_shorten_path.h @@ -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. diff --git a/headers/libs/agg/agg_conv_smooth_poly1.h b/headers/libs/agg/agg_conv_smooth_poly1.h index 2364963305..4ac4e3d6e2 100644 --- a/headers/libs/agg/agg_conv_smooth_poly1.h +++ b/headers/libs/agg/agg_conv_smooth_poly1.h @@ -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. diff --git a/headers/libs/agg/agg_conv_stroke.h b/headers/libs/agg/agg_conv_stroke.h index 707119edfc..e19a6b61f4 100644 --- a/headers/libs/agg/agg_conv_stroke.h +++ b/headers/libs/agg/agg_conv_stroke.h @@ -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); } diff --git a/headers/libs/agg/agg_conv_transform.h b/headers/libs/agg/agg_conv_transform.h index 7e3a392373..1710877481 100644 --- a/headers/libs/agg/agg_conv_transform.h +++ b/headers/libs/agg/agg_conv_transform.h @@ -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 source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: conv_transform(const conv_transform&); const conv_transform& diff --git a/headers/libs/agg/agg_conv_unclose_polygon.h b/headers/libs/agg/agg_conv_unclose_polygon.h index a0619dcd02..66ea45865a 100644 --- a/headers/libs/agg/agg_conv_unclose_polygon.h +++ b/headers/libs/agg/agg_conv_unclose_polygon.h @@ -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 source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: conv_unclose_polygon(const conv_unclose_polygon&); const conv_unclose_polygon& diff --git a/headers/libs/agg/agg_curves.h b/headers/libs/agg/agg_curves.h index 68b40246be..1ef02e8783 100644 --- a/headers/libs/agg/agg_curves.h +++ b/headers/libs/agg/agg_curves.h @@ -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 (tonygeek@yahoo.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. @@ -12,34 +13,35 @@ // mcseemagg@yahoo.com // 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 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 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 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 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; + }; + + + } diff --git a/headers/libs/agg/agg_dda_line.h b/headers/libs/agg/agg_dda_line.h index ead31c9572..f589e76b83 100644 --- a/headers/libs/agg/agg_dda_line.h +++ b/headers/libs/agg/agg_dda_line.h @@ -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 }; //-------------------------------------------------------------------- diff --git a/headers/libs/agg/agg_ellipse.h b/headers/libs/agg/agg_ellipse.h index fcd0d11d65..e78ce27dd9 100644 --- a/headers/libs/agg/agg_ellipse.h +++ b/headers/libs/agg/agg_ellipse.h @@ -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++; diff --git a/headers/libs/agg/agg_ellipse_bresenham.h b/headers/libs/agg/agg_ellipse_bresenham.h index 7ce425b8ae..ee3b9c4638 100644 --- a/headers/libs/agg/agg_ellipse_bresenham.h +++ b/headers/libs/agg/agg_ellipse_bresenham.h @@ -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. diff --git a/headers/libs/agg/agg_embedded_raster_fonts.h b/headers/libs/agg/agg_embedded_raster_fonts.h index 8068de2e97..9d522d671c 100644 --- a/headers/libs/agg/agg_embedded_raster_fonts.h +++ b/headers/libs/agg/agg_embedded_raster_fonts.h @@ -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. diff --git a/headers/libs/agg/agg_font_cache_manager.h b/headers/libs/agg/agg_font_cache_manager.h index 54b0d350d9..e9cf5bf606 100755 --- a/headers/libs/agg/agg_font_cache_manager.h +++ b/headers/libs/agg/agg_font_cache_manager.h @@ -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::deallocate(m_fonts[i]); } - delete [] m_fonts; + pod_allocator::deallocate(m_fonts, m_max_fonts); } //-------------------------------------------------------------------- font_cache_pool(unsigned max_fonts=32) : - m_fonts(new font_cache* [max_fonts]), + m_fonts(pod_allocator::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::deallocate(m_fonts[idx]); + m_fonts[idx] = obj_allocator::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::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::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) { diff --git a/headers/libs/agg/agg_gamma_functions.h b/headers/libs/agg/agg_gamma_functions.h index 527cfd6c59..45facac00c 100644 --- a/headers/libs/agg/agg_gamma_functions.h +++ b/headers/libs/agg/agg_gamma_functions.h @@ -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. diff --git a/headers/libs/agg/agg_gamma_lut.h b/headers/libs/agg/agg_gamma_lut.h index a87ef0a39b..c3e8dfc139 100644 --- a/headers/libs/agg/agg_gamma_lut.h +++ b/headers/libs/agg/agg_gamma_lut.h @@ -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 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::deallocate(m_inv_gamma, hi_res_size); + pod_allocator::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::allocate(gamma_size)), + m_inv_gamma(pod_allocator::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::allocate(gamma_size)), + m_inv_gamma(pod_allocator::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; diff --git a/headers/libs/agg/agg_glyph_raster_bin.h b/headers/libs/agg/agg_glyph_raster_bin.h index cd281830e8..b0bf858efd 100644 --- a/headers/libs/agg/agg_glyph_raster_bin.h +++ b/headers/libs/agg/agg_glyph_raster_bin.h @@ -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. diff --git a/headers/libs/agg/agg_gray8.h b/headers/libs/agg/agg_gray8.h deleted file mode 100755 index 6adc665f18..0000000000 --- a/headers/libs/agg/agg_gray8.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// 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 diff --git a/headers/libs/agg/agg_gsv_text.h b/headers/libs/agg/agg_gsv_text.h index c8c5421ede..269c8a499b 100644 --- a/headers/libs/agg/agg_gsv_text.h +++ b/headers/libs/agg/agg_gsv_text.h @@ -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 m_text_buf; + char* m_cur_chr; + const void* m_font; + pod_array 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); } diff --git a/headers/libs/agg/agg_image_accessors.h b/headers/libs/agg/agg_image_accessors.h new file mode 100644 index 0000000000..1dc7189a1f --- /dev/null +++ b/headers/libs/agg/agg_image_accessors.h @@ -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: mcseem@antigrain.com +// mcseemagg@yahoo.com +// 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 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 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 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 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 diff --git a/headers/libs/agg/agg_image_filters.h b/headers/libs/agg/agg_image_filters.h index 9666ff0f93..8e1bc8f0db 100644 --- a/headers/libs/agg/agg_image_filters.h +++ b/headers/libs/agg/agg_image_filters.h @@ -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 -#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 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 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 m_weight_array; }; //--------------------------------------------------------image_filter - template class image_filter : public image_filter_base + template 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){} }; } diff --git a/headers/libs/agg/agg_line_aa_basics.h b/headers/libs/agg/agg_line_aa_basics.h index 7ae650cad8..c5acb18e79 100644 --- a/headers/libs/agg/agg_line_aa_basics.h +++ b/headers/libs/agg/agg_line_aa_basics.h @@ -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::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 diff --git a/headers/libs/agg/agg_math.h b/headers/libs/agg/agg_math.h index 917e55218b..6d3ff1194b 100644 --- a/headers/libs/agg/agg_math.h +++ b/headers/libs/agg/agg_math.h @@ -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 @@ // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- +// Bessel function (besj) was adapted for use in AGG library by Andy Wilk +// Contact: castor.vulgaris@gmail.com +//---------------------------------------------------------------------------- #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 + // M.Muldoon@UMIST.ac.uk + // + // 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 (castor.vulgaris@gmail.com) + //------------------------------------------------------------------------ + 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; + } + } + } diff --git a/headers/libs/agg/agg_math_stroke.h b/headers/libs/agg/agg_math_stroke.h index 4ee8f45789..c7f0dbdeb6 100644 --- a/headers/libs/agg/agg_math_stroke.h +++ b/headers/libs/agg/agg_math_stroke.h @@ -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 - 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 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 math_stroke::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 void math_stroke::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 void math_stroke::miter_limit_theta(double t) + { + m_miter_limit = 1.0 / sin(t * 0.5) ; + } + + //----------------------------------------------------------------------- + template + void math_stroke::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 - 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 + void math_stroke::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 - 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 + void math_stroke::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 - 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 + void math_stroke::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; } } diff --git a/headers/libs/agg/agg_path_length.h b/headers/libs/agg/agg_path_length.h new file mode 100644 index 0000000000..740ba31df2 --- /dev/null +++ b/headers/libs/agg/agg_path_length.h @@ -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: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_PATH_LENGTH_INCLUDED +#define AGG_PATH_LENGTH_INCLUDED + +#include "agg_math.h" + +namespace agg +{ + template + 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 diff --git a/headers/libs/agg/agg_path_storage.h b/headers/libs/agg/agg_path_storage.h index 277a962abd..141d70466a 100644 --- a/headers/libs/agg/agg_path_storage.h +++ b/headers/libs/agg/agg_path_storage.h @@ -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,12 +16,584 @@ #ifndef AGG_PATH_STORAGE_INCLUDED #define AGG_PATH_STORAGE_INCLUDED -#include "agg_basics.h" +#include +#include +#include "agg_math.h" +#include "agg_array.h" +#include "agg_bezier_arc.h" namespace agg { - //------------------------------------------------------------path_storage + + //----------------------------------------------------vertex_block_storage + template + class vertex_block_storage + { + public: + // Allocation parameters + enum block_scale_e + { + block_shift = BlockShift, + block_size = 1 << block_shift, + block_mask = block_size - 1, + block_pool = BlockPool + }; + + typedef T value_type; + typedef vertex_block_storage self_type; + + ~vertex_block_storage(); + vertex_block_storage(); + vertex_block_storage(const self_type& v); + const self_type& operator = (const self_type& ps); + + void remove_all(); + void free_all(); + + void add_vertex(double x, double y, unsigned cmd); + void modify_vertex(unsigned idx, double x, double y); + void modify_vertex(unsigned idx, double x, double y, unsigned cmd); + void modify_command(unsigned idx, unsigned cmd); + void swap_vertices(unsigned v1, unsigned v2); + + unsigned last_command() const; + unsigned last_vertex(double* x, double* y) const; + unsigned prev_vertex(double* x, double* y) const; + + double last_x() const; + double last_y() const; + + unsigned total_vertices() const; + unsigned vertex(unsigned idx, double* x, double* y) const; + unsigned command(unsigned idx) const; + + private: + void allocate_block(unsigned nb); + int8u* storage_ptrs(T** xy_ptr); + + private: + unsigned m_total_vertices; + unsigned m_total_blocks; + unsigned m_max_blocks; + T** m_coord_blocks; + int8u** m_cmd_blocks; + }; + + + //------------------------------------------------------------------------ + template + void vertex_block_storage::free_all() + { + if(m_total_blocks) + { + T** coord_blk = m_coord_blocks + m_total_blocks - 1; + while(m_total_blocks--) + { + pod_allocator::deallocate( + *coord_blk, + block_size * 2 + + block_size / (sizeof(T) / sizeof(unsigned char))); + --coord_blk; + } + pod_allocator::deallocate(m_coord_blocks, m_max_blocks * 2); + m_total_blocks = 0; + m_max_blocks = 0; + m_coord_blocks = 0; + m_cmd_blocks = 0; + m_total_vertices = 0; + } + } + + //------------------------------------------------------------------------ + template + vertex_block_storage::~vertex_block_storage() + { + free_all(); + } + + //------------------------------------------------------------------------ + template + vertex_block_storage::vertex_block_storage() : + m_total_vertices(0), + m_total_blocks(0), + m_max_blocks(0), + m_coord_blocks(0), + m_cmd_blocks(0) + { + } + + //------------------------------------------------------------------------ + template + vertex_block_storage::vertex_block_storage(const vertex_block_storage& v) : + m_total_vertices(0), + m_total_blocks(0), + m_max_blocks(0), + m_coord_blocks(0), + m_cmd_blocks(0) + { + *this = v; + } + + //------------------------------------------------------------------------ + template + const vertex_block_storage& + vertex_block_storage::operator = (const vertex_block_storage& v) + { + remove_all(); + unsigned i; + for(i = 0; i < v.total_vertices(); i++) + { + double x, y; + unsigned cmd = v.vertex(i, &x, &y); + add_vertex(x, y, cmd); + } + return *this; + } + + //------------------------------------------------------------------------ + template + inline void vertex_block_storage::remove_all() + { + m_total_vertices = 0; + } + + //------------------------------------------------------------------------ + template + inline void vertex_block_storage::add_vertex(double x, double y, + unsigned cmd) + { + T* coord_ptr = 0; + *storage_ptrs(&coord_ptr) = (int8u)cmd; + coord_ptr[0] = T(x); + coord_ptr[1] = T(y); + m_total_vertices++; + } + + //------------------------------------------------------------------------ + template + inline void vertex_block_storage::modify_vertex(unsigned idx, + double x, double y) + { + T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1); + pv[0] = T(x); + pv[1] = T(y); + } + + //------------------------------------------------------------------------ + template + inline void vertex_block_storage::modify_vertex(unsigned idx, + double x, double y, + unsigned cmd) + { + unsigned block = idx >> block_shift; + unsigned offset = idx & block_mask; + T* pv = m_coord_blocks[block] + (offset << 1); + pv[0] = T(x); + pv[1] = T(y); + m_cmd_blocks[block][offset] = (int8u)cmd; + } + + //------------------------------------------------------------------------ + template + inline void vertex_block_storage::modify_command(unsigned idx, + unsigned cmd) + { + m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd; + } + + //------------------------------------------------------------------------ + template + inline void vertex_block_storage::swap_vertices(unsigned v1, unsigned v2) + { + unsigned b1 = v1 >> block_shift; + unsigned b2 = v2 >> block_shift; + unsigned o1 = v1 & block_mask; + unsigned o2 = v2 & block_mask; + T* pv1 = m_coord_blocks[b1] + (o1 << 1); + T* pv2 = m_coord_blocks[b2] + (o2 << 1); + T val; + val = pv1[0]; pv1[0] = pv2[0]; pv2[0] = val; + val = pv1[1]; pv1[1] = pv2[1]; pv2[1] = val; + int8u cmd = m_cmd_blocks[b1][o1]; + m_cmd_blocks[b1][o1] = m_cmd_blocks[b2][o2]; + m_cmd_blocks[b2][o2] = cmd; + } + + //------------------------------------------------------------------------ + template + inline unsigned vertex_block_storage::last_command() const + { + if(m_total_vertices) return command(m_total_vertices - 1); + return path_cmd_stop; + } + + //------------------------------------------------------------------------ + template + inline unsigned vertex_block_storage::last_vertex(double* x, double* y) const + { + if(m_total_vertices) return vertex(m_total_vertices - 1, x, y); + return path_cmd_stop; + } + + //------------------------------------------------------------------------ + template + inline unsigned vertex_block_storage::prev_vertex(double* x, double* y) const + { + if(m_total_vertices > 1) return vertex(m_total_vertices - 2, x, y); + return path_cmd_stop; + } + + //------------------------------------------------------------------------ + template + inline double vertex_block_storage::last_x() const + { + if(m_total_vertices) + { + unsigned idx = m_total_vertices - 1; + return m_coord_blocks[idx >> block_shift][(idx & block_mask) << 1]; + } + return 0.0; + } + + //------------------------------------------------------------------------ + template + inline double vertex_block_storage::last_y() const + { + if(m_total_vertices) + { + unsigned idx = m_total_vertices - 1; + return m_coord_blocks[idx >> block_shift][((idx & block_mask) << 1) + 1]; + } + return 0.0; + } + + //------------------------------------------------------------------------ + template + inline unsigned vertex_block_storage::total_vertices() const + { + return m_total_vertices; + } + + //------------------------------------------------------------------------ + template + inline unsigned vertex_block_storage::vertex(unsigned idx, + double* x, double* y) const + { + unsigned nb = idx >> block_shift; + const T* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1); + *x = pv[0]; + *y = pv[1]; + return m_cmd_blocks[nb][idx & block_mask]; + } + + //------------------------------------------------------------------------ + template + inline unsigned vertex_block_storage::command(unsigned idx) const + { + return m_cmd_blocks[idx >> block_shift][idx & block_mask]; + } + + //------------------------------------------------------------------------ + template + void vertex_block_storage::allocate_block(unsigned nb) + { + if(nb >= m_max_blocks) + { + T** new_coords = + pod_allocator::allocate((m_max_blocks + block_pool) * 2); + + unsigned char** new_cmds = + (unsigned char**)(new_coords + m_max_blocks + block_pool); + + if(m_coord_blocks) + { + memcpy(new_coords, + m_coord_blocks, + m_max_blocks * sizeof(T*)); + + memcpy(new_cmds, + m_cmd_blocks, + m_max_blocks * sizeof(unsigned char*)); + + pod_allocator::deallocate(m_coord_blocks, m_max_blocks * 2); + } + m_coord_blocks = new_coords; + m_cmd_blocks = new_cmds; + m_max_blocks += block_pool; + } + m_coord_blocks[nb] = + pod_allocator::allocate(block_size * 2 + + block_size / (sizeof(T) / sizeof(unsigned char))); + + m_cmd_blocks[nb] = + (unsigned char*)(m_coord_blocks[nb] + block_size * 2); + + m_total_blocks++; + } + + //------------------------------------------------------------------------ + template + int8u* vertex_block_storage::storage_ptrs(T** xy_ptr) + { + unsigned nb = m_total_vertices >> block_shift; + if(nb >= m_total_blocks) + { + allocate_block(nb); + } + *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1); + return m_cmd_blocks[nb] + (m_total_vertices & block_mask); + } + + + + + //-----------------------------------------------------poly_plain_adaptor + template class poly_plain_adaptor + { + public: + typedef T value_type; + + poly_plain_adaptor() : + m_data(0), + m_ptr(0), + m_end(0), + m_closed(false), + m_stop(false) + {} + + poly_plain_adaptor(const T* data, unsigned num_points, bool closed) : + m_data(data), + m_ptr(data), + m_end(data + num_points * 2), + m_closed(closed), + m_stop(false) + {} + + void init(const T* data, unsigned num_points, bool closed) + { + m_data = data; + m_ptr = data; + m_end = data + num_points * 2; + m_closed = closed; + m_stop = false; + } + + void rewind(unsigned) + { + m_ptr = m_data; + m_stop = false; + } + + unsigned vertex(double* x, double* y) + { + if(m_ptr < m_end) + { + bool first = m_ptr == m_data; + *x = *m_ptr++; + *y = *m_ptr++; + return first ? path_cmd_move_to : path_cmd_line_to; + } + *x = *y = 0.0; + if(m_closed && !m_stop) + { + m_stop = true; + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + private: + const T* m_data; + const T* m_ptr; + const T* m_end; + bool m_closed; + bool m_stop; + }; + + + + + + //-------------------------------------------------poly_container_adaptor + template class poly_container_adaptor + { + public: + typedef typename Container::value_type vertex_type; + + poly_container_adaptor() : + m_container(0), + m_index(0), + m_closed(false), + m_stop(false) + {} + + poly_container_adaptor(const Container& data, bool closed) : + m_container(&data), + m_index(0), + m_closed(closed), + m_stop(false) + {} + + void init(const Container& data, bool closed) + { + m_container = &data; + m_index = 0; + m_closed = closed; + m_stop = false; + } + + void rewind(unsigned) + { + m_index = 0; + m_stop = false; + } + + unsigned vertex(double* x, double* y) + { + if(m_index < m_container->size()) + { + bool first = m_index == 0; + const vertex_type& v = (*m_container)[m_index++]; + *x = v.x; + *y = v.y; + return first ? path_cmd_move_to : path_cmd_line_to; + } + *x = *y = 0.0; + if(m_closed && !m_stop) + { + m_stop = true; + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + private: + const Container* m_container; + unsigned m_index; + bool m_closed; + bool m_stop; + }; + + + + //-----------------------------------------poly_container_reverse_adaptor + template class poly_container_reverse_adaptor + { + public: + typedef typename Container::value_type vertex_type; + + poly_container_reverse_adaptor() : + m_container(0), + m_index(-1), + m_closed(false), + m_stop(false) + {} + + poly_container_reverse_adaptor(const Container& data, bool closed) : + m_container(&data), + m_index(-1), + m_closed(closed), + m_stop(false) + {} + + void init(const Container& data, bool closed) + { + m_container = &data; + m_index = m_container->size() - 1; + m_closed = closed; + m_stop = false; + } + + void rewind(unsigned) + { + m_index = m_container->size() - 1; + m_stop = false; + } + + unsigned vertex(double* x, double* y) + { + if(m_index >= 0) + { + bool first = m_index == int(m_container->size() - 1); + const vertex_type& v = (*m_container)[m_index--]; + *x = v.x; + *y = v.y; + return first ? path_cmd_move_to : path_cmd_line_to; + } + *x = *y = 0.0; + if(m_closed && !m_stop) + { + m_stop = true; + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + private: + const Container* m_container; + int m_index; + bool m_closed; + bool m_stop; + }; + + + + + + //--------------------------------------------------------line_adaptor + class line_adaptor + { + public: + typedef double value_type; + + line_adaptor() : m_line(m_coord, 2, false) {} + line_adaptor(double x1, double y1, double x2, double y2) : + m_line(m_coord, 2, false) + { + m_coord[0] = x1; + m_coord[1] = y1; + m_coord[2] = x2; + m_coord[3] = y2; + } + + void init(double x1, double y1, double x2, double y2) + { + m_coord[0] = x1; + m_coord[1] = y1; + m_coord[2] = x2; + m_coord[3] = y2; + m_line.rewind(0); + } + + void rewind(unsigned) + { + m_line.rewind(0); + } + + unsigned vertex(double* x, double* y) + { + return m_line.vertex(x, y); + } + + private: + double m_coord[4]; + poly_plain_adaptor m_line; + }; + + + + + + + + + + + + + + //---------------------------------------------------------------path_base // A container to store vertices with their flags. // A path consists of a number of contours separated with "move_to" // commands. The path storage can keep and maintain more than one @@ -31,86 +603,22 @@ namespace agg // start_new_path() you need to store its return value somewhere else // to navigate to the path afterwards. // - // See Implementation: agg_path_storage.cpp // See also: vertex_source concept //------------------------------------------------------------------------ - class path_storage + template class path_base { - // Allocation parameters - enum - { - block_shift = 8, - block_size = 1 << block_shift, - block_mask = block_size - 1, - block_pool = 256 - }; - public: + typedef VertexContainer container_type; + typedef path_base self_type; //-------------------------------------------------------------------- - class const_iterator - { - void vertex() - { - if(m_vertex_idx < m_path->total_vertices()) - { - m_vertex.cmd = m_path->vertex(m_vertex_idx, &m_vertex.x, &m_vertex.y); - } - else - { - m_vertex.cmd = path_cmd_stop; - m_vertex.x = m_vertex.y = 0.0; - } - } + path_base() : m_vertices(), m_iterator(0) {} + void remove_all() { m_vertices.remove_all(); m_iterator = 0; } + void free_all() { m_vertices.free_all(); m_iterator = 0; } - public: - const_iterator() {} - const_iterator(unsigned cmd) { m_vertex.cmd = cmd; } - const_iterator(const const_iterator& i) : - m_path(i.m_path), - m_vertex_idx(i.m_vertex_idx), - m_vertex(i.m_vertex) - { - } - - const_iterator(const path_storage& p, unsigned id) : - m_path(&p), - m_vertex_idx(id) - { - vertex(); - } - - const_iterator& operator++() - { - ++m_vertex_idx; - vertex(); - return *this; - } - - const vertex_type& operator*() const { return m_vertex; } - const vertex_type* operator->() const { return &m_vertex; } - - bool operator != (const const_iterator& i) - { - return m_vertex.cmd != i.m_vertex.cmd; - } - - private: - const path_storage* m_path; - unsigned m_vertex_idx; - vertex_type m_vertex; - }; - - ~path_storage(); - path_storage(); - path_storage(const path_storage& ps); - - void remove_all(); - - unsigned last_vertex(double* x, double* y) const; - unsigned prev_vertex(double* x, double* y) const; - - void rel_to_abs(double* x, double* y) const; + // Make path functions + //-------------------------------------------------------------------- + unsigned start_new_path(); void move_to(double x, double y); void move_rel(double dx, double dy); @@ -118,6 +626,12 @@ namespace agg void line_to(double x, double y); void line_rel(double dx, double dy); + void hline_to(double x); + void hline_rel(double dx); + + void vline_to(double y); + void vline_rel(double dy); + void arc_to(double rx, double ry, double angle, bool large_arc_flag, @@ -156,151 +670,161 @@ namespace agg void end_poly(unsigned flags = path_flags_close); + void close_polygon(unsigned flags = path_flags_none); - void close_polygon(unsigned flags = path_flags_none) - { - end_poly(path_flags_close | flags); - } + // Accessors + //-------------------------------------------------------------------- + const container_type& vertices() const { return m_vertices; } + container_type& vertices() { return m_vertices; } - void add_poly(const double* vertices, unsigned num, - bool solid_path = false, - unsigned end_flags = path_flags_none); + unsigned total_vertices() const; + void rel_to_abs(double* x, double* y) const; + + unsigned last_vertex(double* x, double* y) const; + unsigned prev_vertex(double* x, double* y) const; + + double last_x() const; + double last_y() const; + + unsigned vertex(unsigned idx, double* x, double* y) const; + unsigned command(unsigned idx) const; + + void modify_vertex(unsigned idx, double x, double y); + void modify_vertex(unsigned idx, double x, double y, unsigned cmd); + void modify_command(unsigned idx, unsigned cmd); + + // VertexSource interface + //-------------------------------------------------------------------- + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + // Arrange the orientation of a polygon, all polygons in a path, + // or in all paths. After calling arrange_orientations() or + // arrange_orientations_all_paths(), all the polygons will have + // the same orientation, i.e. path_flags_cw or path_flags_ccw + //-------------------------------------------------------------------- + unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation); + unsigned arrange_orientations(unsigned path_id, path_flags_e orientation); + void arrange_orientations_all_paths(path_flags_e orientation); + void invert_polygon(unsigned start); + + // Flip all vertices horizontally or vertically, + // between x1 and x2, or between y1 and y2 respectively + //-------------------------------------------------------------------- + void flip_x(double x1, double x2); + void flip_y(double y1, double y2); + + // Concatenate path. The path is added as is. + //-------------------------------------------------------------------- template - void add_path(VertexSource& vs, - unsigned path_id = 0, - bool solid_path = true) + void concat_path(VertexSource& vs, unsigned path_id = 0) { double x, y; unsigned cmd; vs.rewind(path_id); while(!is_stop(cmd = vs.vertex(&x, &y))) { - if(is_move_to(cmd) && solid_path && m_total_vertices) - { - cmd = path_cmd_line_to; - } - add_vertex(x, y, cmd); + m_vertices.add_vertex(x, y, cmd); } } - unsigned start_new_path(); - - void copy_from(const path_storage& ps); - const path_storage& operator = (const path_storage& ps) + //-------------------------------------------------------------------- + // Join path. The path is joined with the existing one, that is, + // it behaves as if the pen of a plotter was always down (drawing) + template + void join_path(VertexSource& vs, unsigned path_id = 0) { - copy_from(ps); - return *this; + double x, y; + unsigned cmd; + vs.rewind(path_id); + cmd = vs.vertex(&x, &y); + if(!is_stop(cmd)) + { + if(is_vertex(cmd)) + { + double x0, y0; + unsigned cmd0 = last_vertex(&x0, &y0); + if(is_vertex(cmd0)) + { + if(calc_distance(x, y, x0, y0) > vertex_dist_epsilon) + { + if(is_move_to(cmd)) cmd = path_cmd_line_to; + m_vertices.add_vertex(x, y, cmd); + } + } + else + { + if(is_stop(cmd0)) + { + cmd = path_cmd_move_to; + } + else + { + if(is_move_to(cmd)) cmd = path_cmd_line_to; + } + m_vertices.add_vertex(x, y, cmd); + } + } + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + m_vertices.add_vertex(x, y, is_move_to(cmd) ? + path_cmd_line_to : + cmd); + } + } } - - unsigned total_vertices() const { return m_total_vertices; } - unsigned vertex(unsigned idx, double* x, double* y) const + // Concatenate polygon/polyline. + //-------------------------------------------------------------------- + template void concat_poly(const T* data, + unsigned num_points, + bool closed) { - unsigned nb = idx >> block_shift; - const double* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1); - *x = *pv++; - *y = *pv; - return m_cmd_blocks[nb][idx & block_mask]; - } - unsigned command(unsigned idx) const - { - return m_cmd_blocks[idx >> block_shift][idx & block_mask]; + poly_plain_adaptor poly(data, num_points, closed); + concat_path(poly); } - void rewind(unsigned path_id); - unsigned vertex(double* x, double* y); - - const_iterator begin(unsigned id) const { return const_iterator(*this, id); } - const_iterator begin() const { return const_iterator(*this, 0); } - const_iterator end() const { return const_iterator(path_cmd_stop); } - - // Arrange the orientation of all the polygons. After calling this - // method all the polygons will have the same orientation - // determined by the new_orientation flag, i.e., - // path_flags_cw or path_flags_ccw - unsigned arrange_orientations(unsigned path_id, path_flags_e new_orientation); - void arrange_orientations_all_paths(path_flags_e new_orientation); - - // Flip all the vertices horizontally or vertically - void flip_x(double x1, double x2); - void flip_y(double y1, double y2); - - // This function adds a vertex with its flags directly. Since there's no - // checking for errors, keeping proper path integrity is the responsibility - // of the caller. It can be said the function is "not very public". - void add_vertex(double x, double y, unsigned cmd); - - // Allows you to modify vertex coordinates. The caller must know - // the index of the vertex. - void modify_vertex(unsigned idx, double x, double y) + // Join polygon/polyline continuously. + //-------------------------------------------------------------------- + template void join_poly(const T* data, + unsigned num_points, + bool closed) { - double* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1); - *pv++ = x; - *pv = y; - } - - // Allows you to modify vertex command. The caller must know - // the index of the vertex. - void modify_command(unsigned idx, unsigned cmd) - { - m_cmd_blocks[idx >> block_shift][idx & block_mask] = (unsigned char)cmd; + poly_plain_adaptor poly(data, num_points, closed); + join_path(poly); } private: - void allocate_block(unsigned nb); - unsigned char* storage_ptrs(double** xy_ptr); - unsigned perceive_polygon_orientation(unsigned idx, - double xs, double ys, - unsigned* orientation); - void reverse_polygon(unsigned start, unsigned end); + unsigned perceive_polygon_orientation(unsigned start, unsigned end); + void invert_polygon(unsigned start, unsigned end); - private: - unsigned m_total_vertices; - unsigned m_total_blocks; - unsigned m_max_blocks; - double** m_coord_blocks; - unsigned char** m_cmd_blocks; + VertexContainer m_vertices; unsigned m_iterator; }; - //------------------------------------------------------------------------ - inline unsigned path_storage::vertex(double* x, double* y) + template + unsigned path_base::start_new_path() { - if(m_iterator >= m_total_vertices) return path_cmd_stop; - return vertex(m_iterator++, x, y); - } - - //------------------------------------------------------------------------ - inline unsigned path_storage::prev_vertex(double* x, double* y) const - { - if(m_total_vertices > 1) + if(!is_stop(m_vertices.last_command())) { - return vertex(m_total_vertices - 2, x, y); + m_vertices.add_vertex(0.0, 0.0, path_cmd_stop); } - return path_cmd_stop; + return m_vertices.total_vertices(); } - //------------------------------------------------------------------------ - inline unsigned path_storage::last_vertex(double* x, double* y) const - { - if(m_total_vertices) - { - return vertex(m_total_vertices - 1, x, y); - } - return path_cmd_stop; - } //------------------------------------------------------------------------ - inline void path_storage::rel_to_abs(double* x, double* y) const + template + inline void path_base::rel_to_abs(double* x, double* y) const { - if(m_total_vertices) + if(m_vertices.total_vertices()) { double x2; double y2; - if(is_vertex(vertex(m_total_vertices - 1, &x2, &y2))) + if(is_vertex(m_vertices.last_vertex(&x2, &y2))) { *x += x2; *y += y2; @@ -309,56 +833,646 @@ namespace agg } //------------------------------------------------------------------------ - inline unsigned char* path_storage::storage_ptrs(double** xy_ptr) + template + inline void path_base::move_to(double x, double y) { - unsigned nb = m_total_vertices >> block_shift; - if(nb >= m_total_blocks) + m_vertices.add_vertex(x, y, path_cmd_move_to); + } + + //------------------------------------------------------------------------ + template + inline void path_base::move_rel(double dx, double dy) + { + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_move_to); + } + + //------------------------------------------------------------------------ + template + inline void path_base::line_to(double x, double y) + { + m_vertices.add_vertex(x, y, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template + inline void path_base::line_rel(double dx, double dy) + { + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template + inline void path_base::hline_to(double x) + { + m_vertices.add_vertex(x, last_y(), path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template + inline void path_base::hline_rel(double dx) + { + double dy = 0; + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template + inline void path_base::vline_to(double y) + { + m_vertices.add_vertex(last_x(), y, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template + inline void path_base::vline_rel(double dy) + { + double dx = 0; + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template + void path_base::arc_to(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x, double y) + { + if(m_vertices.total_vertices() && is_vertex(m_vertices.last_command())) { - allocate_block(nb); + const double epsilon = 1e-30; + double x0 = 0.0; + double y0 = 0.0; + m_vertices.last_vertex(&x0, &y0); + + rx = fabs(rx); + ry = fabs(ry); + + // Ensure radii are valid + //------------------------- + if(rx < epsilon || ry < epsilon) + { + line_to(x, y); + return; + } + + if(calc_distance(x0, y0, x, y) < epsilon) + { + // If the endpoints (x, y) and (x0, y0) are identical, then this + // is equivalent to omitting the elliptical arc segment entirely. + return; + } + bezier_arc_svg a(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x, y); + if(a.radii_ok()) + { + join_path(a); + } + else + { + line_to(x, y); + } + } + else + { + move_to(x, y); } - *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1); - return m_cmd_blocks[nb] + (m_total_vertices & block_mask); - } - - - //------------------------------------------------------------------------ - inline void path_storage::add_vertex(double x, double y, unsigned cmd) - { - double* coord_ptr = 0; - unsigned char* cmd_ptr = storage_ptrs(&coord_ptr); - *cmd_ptr = (unsigned char)cmd; - *coord_ptr++ = x; - *coord_ptr = y; - m_total_vertices++; } //------------------------------------------------------------------------ - inline void path_storage::move_to(double x, double y) - { - add_vertex(x, y, path_cmd_move_to); - } - - //------------------------------------------------------------------------ - inline void path_storage::move_rel(double dx, double dy) + template + void path_base::arc_rel(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double dx, double dy) { rel_to_abs(&dx, &dy); - add_vertex(dx, dy, path_cmd_move_to); + arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy); } //------------------------------------------------------------------------ - inline void path_storage::line_to(double x, double y) + template + void path_base::curve3(double x_ctrl, double y_ctrl, + double x_to, double y_to) { - add_vertex(x, y, path_cmd_line_to); + m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); + m_vertices.add_vertex(x_to, y_to, path_cmd_curve3); } //------------------------------------------------------------------------ - inline void path_storage::line_rel(double dx, double dy) + template + void path_base::curve3_rel(double dx_ctrl, double dy_ctrl, + double dx_to, double dy_to) { - rel_to_abs(&dx, &dy); - add_vertex(dx, dy, path_cmd_line_to); + rel_to_abs(&dx_ctrl, &dy_ctrl); + rel_to_abs(&dx_to, &dy_to); + m_vertices.add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3); + m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve3); } + + //------------------------------------------------------------------------ + template + void path_base::curve3(double x_to, double y_to) + { + double x0; + double y0; + if(is_vertex(m_vertices.last_vertex(&x0, &y0))) + { + double x_ctrl; + double y_ctrl; + unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl); + if(is_curve(cmd)) + { + x_ctrl = x0 + x0 - x_ctrl; + y_ctrl = y0 + y0 - y_ctrl; + } + else + { + x_ctrl = x0; + y_ctrl = y0; + } + curve3(x_ctrl, y_ctrl, x_to, y_to); + } + } + + //------------------------------------------------------------------------ + template + void path_base::curve3_rel(double dx_to, double dy_to) + { + rel_to_abs(&dx_to, &dy_to); + curve3(dx_to, dy_to); + } + + //------------------------------------------------------------------------ + template + void path_base::curve4(double x_ctrl1, double y_ctrl1, + double x_ctrl2, double y_ctrl2, + double x_to, double y_to) + { + m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); + m_vertices.add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4); + m_vertices.add_vertex(x_to, y_to, path_cmd_curve4); + } + + //------------------------------------------------------------------------ + template + void path_base::curve4_rel(double dx_ctrl1, double dy_ctrl1, + double dx_ctrl2, double dy_ctrl2, + double dx_to, double dy_to) + { + rel_to_abs(&dx_ctrl1, &dy_ctrl1); + rel_to_abs(&dx_ctrl2, &dy_ctrl2); + rel_to_abs(&dx_to, &dy_to); + m_vertices.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4); + m_vertices.add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4); + m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve4); + } + + //------------------------------------------------------------------------ + template + void path_base::curve4(double x_ctrl2, double y_ctrl2, + double x_to, double y_to) + { + double x0; + double y0; + if(is_vertex(last_vertex(&x0, &y0))) + { + double x_ctrl1; + double y_ctrl1; + unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1); + if(is_curve(cmd)) + { + x_ctrl1 = x0 + x0 - x_ctrl1; + y_ctrl1 = y0 + y0 - y_ctrl1; + } + else + { + x_ctrl1 = x0; + y_ctrl1 = y0; + } + curve4(x_ctrl1, y_ctrl1, x_ctrl2, y_ctrl2, x_to, y_to); + } + } + + //------------------------------------------------------------------------ + template + void path_base::curve4_rel(double dx_ctrl2, double dy_ctrl2, + double dx_to, double dy_to) + { + rel_to_abs(&dx_ctrl2, &dy_ctrl2); + rel_to_abs(&dx_to, &dy_to); + curve4(dx_ctrl2, dy_ctrl2, dx_to, dy_to); + } + + //------------------------------------------------------------------------ + template + inline void path_base::end_poly(unsigned flags) + { + if(is_vertex(m_vertices.last_command())) + { + m_vertices.add_vertex(0.0, 0.0, path_cmd_end_poly | flags); + } + } + + //------------------------------------------------------------------------ + template + inline void path_base::close_polygon(unsigned flags) + { + end_poly(path_flags_close | flags); + } + + //------------------------------------------------------------------------ + template + inline unsigned path_base::total_vertices() const + { + return m_vertices.total_vertices(); + } + + //------------------------------------------------------------------------ + template + inline unsigned path_base::last_vertex(double* x, double* y) const + { + return m_vertices.last_vertex(x, y); + } + + //------------------------------------------------------------------------ + template + inline unsigned path_base::prev_vertex(double* x, double* y) const + { + return m_vertices.prev_vertex(x, y); + } + + //------------------------------------------------------------------------ + template + inline double path_base::last_x() const + { + return m_vertices.last_x(); + } + + //------------------------------------------------------------------------ + template + inline double path_base::last_y() const + { + return m_vertices.last_y(); + } + + //------------------------------------------------------------------------ + template + inline unsigned path_base::vertex(unsigned idx, double* x, double* y) const + { + return m_vertices.vertex(idx, x, y); + } + + //------------------------------------------------------------------------ + template + inline unsigned path_base::command(unsigned idx) const + { + return m_vertices.command(idx); + } + + //------------------------------------------------------------------------ + template + void path_base::modify_vertex(unsigned idx, double x, double y) + { + m_vertices.modify_vertex(idx, x, y); + } + + //------------------------------------------------------------------------ + template + void path_base::modify_vertex(unsigned idx, double x, double y, unsigned cmd) + { + m_vertices.modify_vertex(idx, x, y, cmd); + } + + //------------------------------------------------------------------------ + template + void path_base::modify_command(unsigned idx, unsigned cmd) + { + m_vertices.modify_command(idx, cmd); + } + + //------------------------------------------------------------------------ + template + inline void path_base::rewind(unsigned path_id) + { + m_iterator = path_id; + } + + //------------------------------------------------------------------------ + template + inline unsigned path_base::vertex(double* x, double* y) + { + if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop; + return m_vertices.vertex(m_iterator++, x, y); + } + + + //------------------------------------------------------------------------ + template + unsigned path_base::perceive_polygon_orientation(unsigned start, + unsigned end) + { + // Calculate signed area (double area to be exact) + //--------------------- + unsigned np = end - start; + double area = 0.0; + unsigned i; + for(i = 0; i < np; i++) + { + double x1, y1, x2, y2; + m_vertices.vertex(start + i, &x1, &y1); + m_vertices.vertex(start + (i + 1) % np, &x2, &y2); + area += x1 * y2 - y1 * x2; + } + return (area < 0.0) ? path_flags_cw : path_flags_ccw; + } + + + //------------------------------------------------------------------------ + template + void path_base::invert_polygon(unsigned start, unsigned end) + { + unsigned i; + unsigned tmp_cmd = m_vertices.command(start); + + --end; // Make "end" inclusive + + // Shift all commands to one position + for(i = start; i < end; i++) + { + m_vertices.modify_command(i, m_vertices.command(i + 1)); + } + + // Assign starting command to the ending command + m_vertices.modify_command(end, tmp_cmd); + + // Reverse the polygon + while(end > start) + { + m_vertices.swap_vertices(start++, end--); + } + } + + //------------------------------------------------------------------------ + template + void path_base::invert_polygon(unsigned start) + { + // Skip all non-vertices at the beginning + while(start < m_vertices.total_vertices() && + !is_vertex(m_vertices.command(start))) ++start; + + // Skip all insignificant move_to + while(start+1 < m_vertices.total_vertices() && + is_move_to(m_vertices.command(start)) && + is_move_to(m_vertices.command(start+1))) ++start; + + // Find the last vertex + unsigned end = start + 1; + while(end < m_vertices.total_vertices() && + !is_next_poly(m_vertices.command(end))) ++end; + + invert_polygon(start, end); + } + + //------------------------------------------------------------------------ + template + unsigned path_base::arrange_polygon_orientation(unsigned start, + path_flags_e orientation) + { + if(orientation == path_flags_none) return start; + + // Skip all non-vertices at the beginning + while(start < m_vertices.total_vertices() && + !is_vertex(m_vertices.command(start))) ++start; + + // Skip all insignificant move_to + while(start+1 < m_vertices.total_vertices() && + is_move_to(m_vertices.command(start)) && + is_move_to(m_vertices.command(start+1))) ++start; + + // Find the last vertex + unsigned end = start + 1; + while(end < m_vertices.total_vertices() && + !is_next_poly(m_vertices.command(end))) ++end; + + if(end - start > 2) + { + if(perceive_polygon_orientation(start, end) != unsigned(orientation)) + { + // Invert polygon, set orientation flag, and skip all end_poly + invert_polygon(start, end); + unsigned cmd; + while(end < m_vertices.total_vertices() && + is_end_poly(cmd = m_vertices.command(end))) + { + m_vertices.modify_command(end++, set_orientation(cmd, orientation)); + } + } + } + return end; + } + + + //------------------------------------------------------------------------ + template + unsigned path_base::arrange_orientations(unsigned start, + path_flags_e orientation) + { + if(orientation != path_flags_none) + { + while(start < m_vertices.total_vertices()) + { + start = arrange_polygon_orientation(start, orientation); + if(is_stop(m_vertices.command(start))) + { + ++start; + break; + } + } + } + return start; + } + + + //------------------------------------------------------------------------ + template + void path_base::arrange_orientations_all_paths(path_flags_e orientation) + { + if(orientation != path_flags_none) + { + unsigned start = 0; + while(start < m_vertices.total_vertices()) + { + start = arrange_orientations(start, orientation); + } + } + } + + + //------------------------------------------------------------------------ + template + void path_base::flip_x(double x1, double x2) + { + unsigned i; + double x, y; + for(i = 0; i < m_vertices.total_vertices(); i++) + { + unsigned cmd = m_vertices.vertex(i, &x, &y); + if(is_vertex(cmd)) + { + m_vertices.modify_vertex(i, x2 - x + x1, y); + } + } + } + + + //------------------------------------------------------------------------ + template + void path_base::flip_y(double y1, double y2) + { + unsigned i; + double x, y; + for(i = 0; i < m_vertices.total_vertices(); i++) + { + unsigned cmd = m_vertices.vertex(i, &x, &y); + if(is_vertex(cmd)) + { + m_vertices.modify_vertex(i, x, y2 - y + y1); + } + } + } + + + + + + //-----------------------------------------------------vertex_stl_storage + template class vertex_stl_storage + { + public: + typedef typename Container::value_type vertex_type; + typedef typename vertex_type::value_type value_type; + + void remove_all() { m_vertices.clear(); } + void free_all() { m_vertices.clear(); } + + void add_vertex(double x, double y, unsigned cmd) + { + m_vertices.push_back(vertex_type(value_type(x), + value_type(y), + int8u(cmd))); + } + + void modify_vertex(unsigned idx, double x, double y) + { + vertex_type& v = m_vertices[idx]; + v.x = value_type(x); + v.y = value_type(y); + } + + void modify_vertex(unsigned idx, double x, double y, unsigned cmd) + { + vertex_type& v = m_vertices[idx]; + v.x = value_type(x); + v.y = value_type(y); + v.cmd = int8u(cmd); + } + + void modify_command(unsigned idx, unsigned cmd) + { + m_vertices[idx].cmd = int8u(cmd); + } + + void swap_vertices(unsigned v1, unsigned v2) + { + vertex_type t = m_vertices[v1]; + m_vertices[v1] = m_vertices[v2]; + m_vertices[v2] = t; + } + + unsigned last_command() const + { + return m_vertices.size() ? + m_vertices[m_vertices.size() - 1].cmd : + path_cmd_stop; + } + + unsigned last_vertex(double* x, double* y) const + { + if(m_vertices.size() == 0) + { + *x = *y = 0.0; + return path_cmd_stop; + } + return vertex(m_vertices.size() - 1, x, y); + } + + unsigned prev_vertex(double* x, double* y) const + { + if(m_vertices.size() < 2) + { + *x = *y = 0.0; + return path_cmd_stop; + } + return vertex(m_vertices.size() - 2, x, y); + } + + double last_x() const + { + return m_vertices.size() ? m_vertices[m_vertices.size() - 1].x : 0.0; + } + + double last_y() const + { + return m_vertices.size() ? m_vertices[m_vertices.size() - 1].y : 0.0; + } + + unsigned total_vertices() const + { + return m_vertices.size(); + } + + unsigned vertex(unsigned idx, double* x, double* y) const + { + const vertex_type& v = m_vertices[idx]; + *x = v.x; + *y = v.y; + return v.cmd; + } + + unsigned command(unsigned idx) const + { + return m_vertices[idx].cmd; + } + + private: + Container m_vertices; + }; + + //-----------------------------------------------------------path_storage + typedef path_base > path_storage; + + // Example of declarations path_storage with pod_bvector as a container + //----------------------------------------------------------------------- + //typedef path_base > > path_storage; + } +// Example of declarations path_storage with std::vector as a container +//--------------------------------------------------------------------------- +//#include +//namespace agg +//{ +// typedef path_base > > stl_path_storage; +//} + + + + #endif diff --git a/headers/libs/agg/agg_path_storage_integer.h b/headers/libs/agg/agg_path_storage_integer.h index 2773336522..7c48355993 100755 --- a/headers/libs/agg/agg_path_storage_integer.h +++ b/headers/libs/agg/agg_path_storage_integer.h @@ -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 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 path_storage_integer { public: + typedef T value_type; typedef vertex_integer 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 m_storage; - unsigned m_vertex_idx; - bool m_closed; + pod_bvector m_storage; + unsigned m_vertex_idx; + bool m_closed; }; diff --git a/headers/libs/agg/agg_pattern_filters_rgba8.h b/headers/libs/agg/agg_pattern_filters_rgba.h similarity index 55% rename from headers/libs/agg/agg_pattern_filters_rgba8.h rename to headers/libs/agg/agg_pattern_filters_rgba.h index 51f49f1c4b..9fb8afa6cf 100644 --- a/headers/libs/agg/agg_pattern_filters_rgba8.h +++ b/headers/libs/agg/agg_pattern_filters_rgba.h @@ -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 pattern_filter_nn_rgba8; + typedef pattern_filter_nn pattern_filter_nn_rgba8; + typedef pattern_filter_nn pattern_filter_nn_rgba16; - - //===========================================pattern_filter_bilinear_rgba8 - struct pattern_filter_bilinear_rgba8 + //===========================================pattern_filter_bilinear_rgba + template 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 pattern_filter_bilinear_rgba8; + typedef pattern_filter_bilinear_rgba pattern_filter_bilinear_rgba16; } #endif diff --git a/headers/libs/agg/agg_pixfmt_amask_adaptor.h b/headers/libs/agg/agg_pixfmt_amask_adaptor.h index 3848374bfa..1f2c12e9d8 100644 --- a/headers/libs/agg/agg_pixfmt_amask_adaptor.h +++ b/headers/libs/agg/agg_pixfmt_amask_adaptor.h @@ -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 +#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 + 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 m_span; }; } diff --git a/headers/libs/agg/agg_pixfmt_crb_rgba32.h b/headers/libs/agg/agg_pixfmt_crb_rgba32.h deleted file mode 100644 index fe045261ee..0000000000 --- a/headers/libs/agg/agg_pixfmt_crb_rgba32.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_CRB_RGBA32_INCLUDED -#define AGG_PIXFMT_CRB_RGBA32_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_color_rgba8.h" - -namespace agg -{ - - //================================================pixel_formats_crb_rgba32 - template 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 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 - 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 - diff --git a/headers/libs/agg/agg_pixfmt_crb_rgba32_pre.h b/headers/libs/agg/agg_pixfmt_crb_rgba32_pre.h deleted file mode 100644 index c666089ea9..0000000000 --- a/headers/libs/agg/agg_pixfmt_crb_rgba32_pre.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_CRB_RGBA32_PRE_INCLUDED -#define AGG_PIXFMT_CRB_RGBA32_PRE_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_color_rgba8.h" - -namespace agg -{ - - //============================================pixel_formats_crb_rgba32_pre - template 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 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 - 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 - diff --git a/headers/libs/agg/agg_pixfmt_gray.h b/headers/libs/agg/agg_pixfmt_gray.h new file mode 100644 index 0000000000..08b3d7d3e5 --- /dev/null +++ b/headers/libs/agg/agg_pixfmt_gray.h @@ -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: mcseem@antigrain.com +// mcseemagg@yahoo.com +// 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 +#include "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + + //============================================================blender_gray + template 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 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 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 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 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 + 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 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 void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_gray(g)); + } + + //-------------------------------------------------------------------- + template void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_gray(g)); + } + + //-------------------------------------------------------------------- + template + 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 blender_gray8; + typedef blender_gray_pre blender_gray8_pre; + typedef blender_gray blender_gray16; + typedef blender_gray_pre blender_gray16_pre; + + typedef pixfmt_alpha_blend_gray pixfmt_gray8; //----pixfmt_gray8 + typedef pixfmt_alpha_blend_gray pixfmt_gray8_pre; //----pixfmt_gray8_pre + typedef pixfmt_alpha_blend_gray pixfmt_gray16; //----pixfmt_gray16 + typedef pixfmt_alpha_blend_gray pixfmt_gray16_pre; //----pixfmt_gray16_pre +} + +#endif + diff --git a/headers/libs/agg/agg_pixfmt_gray8.h b/headers/libs/agg/agg_pixfmt_gray8.h deleted file mode 100644 index df37dfe7d5..0000000000 --- a/headers/libs/agg/agg_pixfmt_gray8.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_GRAY8_INCLUDED -#define AGG_PIXFMT_GRAY8_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_gray8.h" -#include "agg_rendering_buffer.h" - -namespace agg -{ - - //======================================================pixfmt_gray8_base - template - 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 - diff --git a/headers/libs/agg/agg_pixfmt_rgb.h b/headers/libs/agg/agg_pixfmt_rgb.h new file mode 100644 index 0000000000..51450cf12e --- /dev/null +++ b/headers/libs/agg/agg_pixfmt_rgb.h @@ -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: mcseem@antigrain.com +// mcseemagg@yahoo.com +// 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 +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + + //=====================================================apply_gamma_dir_rgb + template 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 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 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 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 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 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 + 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 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 void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_rgb(g)); + } + + //-------------------------------------------------------------------- + template void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_rgb(g)); + } + + //-------------------------------------------------------------------- + template + 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 + 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, rendering_buffer> pixfmt_rgb24; //----pixfmt_rgb24 + typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_bgr24; //----pixfmt_bgr24 + typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_rgb48; //----pixfmt_rgb48 + typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_bgr48; //----pixfmt_bgr48 + + typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_rgb24_pre; //----pixfmt_rgb24_pre + typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_bgr24_pre; //----pixfmt_bgr24_pre + typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_rgb48_pre; //----pixfmt_rgb48_pre + typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_bgr48_pre; //----pixfmt_bgr48_pre + + //-----------------------------------------------------pixfmt_rgb24_gamma + template class pixfmt_rgb24_gamma : + public pixfmt_alpha_blend_rgb, rendering_buffer> + { + public: + pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb, rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_bgr24_gamma + template class pixfmt_bgr24_gamma : + public pixfmt_alpha_blend_rgb, rendering_buffer> + { + public: + pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb, rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_rgb48_gamma + template class pixfmt_rgb48_gamma : + public pixfmt_alpha_blend_rgb, rendering_buffer> + { + public: + pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb, rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_bgr48_gamma + template class pixfmt_bgr48_gamma : + public pixfmt_alpha_blend_rgb, rendering_buffer> + { + public: + pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb, rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + +} + +#endif + diff --git a/headers/libs/agg/agg_pixfmt_rgb24.h b/headers/libs/agg/agg_pixfmt_rgb24.h deleted file mode 100644 index 5482d53d83..0000000000 --- a/headers/libs/agg/agg_pixfmt_rgb24.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_RGB24_INCLUDED -#define AGG_PIXFMT_RGB24_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_rendering_buffer.h" - -namespace agg -{ - - //=====================================================pixel_formats_rgb24 - template 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 pixfmt_rgb24; //----pixfmt_rgb24 - typedef pixel_formats_rgb24 pixfmt_bgr24; //----pixfmt_bgr24 - -} - -#endif - diff --git a/headers/libs/agg/agg_pixfmt_rgb24_gamma.h b/headers/libs/agg/agg_pixfmt_rgb24_gamma.h deleted file mode 100644 index c5be4b66cd..0000000000 --- a/headers/libs/agg/agg_pixfmt_rgb24_gamma.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_RGB24_GAMMA_INCLUDED -#define AGG_PIXFMT_RGB24_GAMMA_INCLUDED - -#include -#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 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 pixfmt_rgb24_gamma : - public pixel_formats_rgb24_gamma - { - public: - pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) : - pixel_formats_rgb24_gamma(rb, g) {} - }; - - //-----------------------------------------------------pixfmt_bgr24_gamma - template class pixfmt_bgr24_gamma : - public pixel_formats_rgb24_gamma - { - public: - pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) : - pixel_formats_rgb24_gamma(rb, g) {} - }; - - - -} - -#endif diff --git a/headers/libs/agg/agg_pixfmt_rgb24_pre.h b/headers/libs/agg/agg_pixfmt_rgb24_pre.h deleted file mode 100644 index 67b10b3524..0000000000 --- a/headers/libs/agg/agg_pixfmt_rgb24_pre.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_RGB24_PRE_INCLUDED -#define AGG_PIXFMT_RGB24_PRE_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_rendering_buffer.h" - -namespace agg -{ - - - //==================================================pixel_formats_rgb24_pre - template 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 pixfmt_rgb24_pre; //----pixfmt_rgb24_pre - typedef pixel_formats_rgb24_pre pixfmt_bgr24_pre; //----pixfmt_bgr24_pre -} - - -#endif diff --git a/headers/libs/agg/agg_pixfmt_rgb555.h b/headers/libs/agg/agg_pixfmt_rgb555.h deleted file mode 100644 index 2f8f5fc5b9..0000000000 --- a/headers/libs/agg/agg_pixfmt_rgb555.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_RGB555_INCLUDED -#define AGG_PIXFMT_RGB555_INCLUDED - -#include -#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 - diff --git a/headers/libs/agg/agg_pixfmt_rgb565.h b/headers/libs/agg/agg_pixfmt_rgb565.h deleted file mode 100644 index 88c4021207..0000000000 --- a/headers/libs/agg/agg_pixfmt_rgb565.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_RGB565_INCLUDED -#define AGG_PIXFMT_RGB565_INCLUDED - -#include -#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 - diff --git a/headers/libs/agg/agg_pixfmt_rgb_packed.h b/headers/libs/agg/agg_pixfmt_rgb_packed.h new file mode 100644 index 0000000000..7868085250 --- /dev/null +++ b/headers/libs/agg/agg_pixfmt_rgb_packed.h @@ -0,0 +1,1250 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_PACKED_INCLUDED +#define AGG_PIXFMT_RGB_PACKED_INCLUDED + +#include +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + //=========================================================blender_rgb555 + struct blender_rgb555 + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = (rgb >> 7) & 0xF8; + calc_type g = (rgb >> 2) & 0xF8; + calc_type b = (rgb << 3) & 0xF8; + *p = (pixel_type) + (((((cr - r) * alpha + (r << 8)) >> 1) & 0x7C00) | + ((((cg - g) * alpha + (g << 8)) >> 6) & 0x03E0) | + (((cb - b) * alpha + (b << 8)) >> 11) | 0x8000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (b >> 3) | 0x8000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 7) & 0xF8, + (p >> 2) & 0xF8, + (p << 3) & 0xF8); + } + }; + + + //=====================================================blender_rgb555_pre + struct blender_rgb555_pre + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + pixel_type rgb = *p; + calc_type r = (rgb >> 7) & 0xF8; + calc_type g = (rgb >> 2) & 0xF8; + calc_type b = (rgb << 3) & 0xF8; + *p = (pixel_type) + ((((r * alpha + cr * cover) >> 1) & 0x7C00) | + (((g * alpha + cg * cover) >> 6) & 0x03E0) | + ((b * alpha + cb * cover) >> 11) | 0x8000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (b >> 3) | 0x8000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 7) & 0xF8, + (p >> 2) & 0xF8, + (p << 3) & 0xF8); + } + }; + + + + + //=====================================================blender_rgb555_gamma + template class blender_rgb555_gamma + { + public: + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + typedef Gamma gamma_type; + + blender_rgb555_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = m_gamma->dir((rgb >> 7) & 0xF8); + calc_type g = m_gamma->dir((rgb >> 2) & 0xF8); + calc_type b = m_gamma->dir((rgb << 3) & 0xF8); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 7) & 0x7C00) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 2) & 0x03E0) | + (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3) | 0x8000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (b >> 3) | 0x8000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 7) & 0xF8, + (p >> 2) & 0xF8, + (p << 3) & 0xF8); + } + + private: + const Gamma* m_gamma; + }; + + + + + + //=========================================================blender_rgb565 + struct blender_rgb565 + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = (rgb >> 8) & 0xF8; + calc_type g = (rgb >> 3) & 0xFC; + calc_type b = (rgb << 3) & 0xF8; + *p = (pixel_type) + (((((cr - r) * alpha + (r << 8)) ) & 0xF800) | + ((((cg - g) * alpha + (g << 8)) >> 5) & 0x07E0) | + (((cb - b) * alpha + (b << 8)) >> 11)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 8) & 0xF8, + (p >> 3) & 0xFC, + (p << 3) & 0xF8); + } + }; + + + + //=====================================================blender_rgb565_pre + struct blender_rgb565_pre + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + pixel_type rgb = *p; + calc_type r = (rgb >> 8) & 0xF8; + calc_type g = (rgb >> 3) & 0xFC; + calc_type b = (rgb << 3) & 0xF8; + *p = (pixel_type) + ((((r * alpha + cr * cover) ) & 0xF800) | + (((g * alpha + cg * cover) >> 5 ) & 0x07E0) | + ((b * alpha + cb * cover) >> 11)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 8) & 0xF8, + (p >> 3) & 0xFC, + (p << 3) & 0xF8); + } + }; + + + + //=====================================================blender_rgb565_gamma + template class blender_rgb565_gamma + { + public: + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + typedef Gamma gamma_type; + + blender_rgb565_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = m_gamma->dir((rgb >> 8) & 0xF8); + calc_type g = m_gamma->dir((rgb >> 3) & 0xFC); + calc_type b = m_gamma->dir((rgb << 3) & 0xF8); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 8) & 0xF800) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 3) & 0x07E0) | + (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 8) & 0xF8, + (p >> 3) & 0xFC, + (p << 3) & 0xF8); + } + + private: + const Gamma* m_gamma; + }; + + + + //=====================================================blender_rgbAAA + struct blender_rgbAAA + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = (rgb >> 14) & 0xFFC0; + calc_type g = (rgb >> 4) & 0xFFC0; + calc_type b = (rgb << 6) & 0xFFC0; + *p = (pixel_type) + (((((cr - r) * alpha + (r << 16)) >> 2) & 0x3FF00000) | + ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) | + (((cb - b) * alpha + (b << 16)) >> 22) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (b >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 14) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p << 6) & 0xFFC0); + } + }; + + + + //==================================================blender_rgbAAA_pre + struct blender_rgbAAA_pre + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + cover = (cover + 1) << (color_type::base_shift - 8); + pixel_type rgb = *p; + calc_type r = (rgb >> 14) & 0xFFC0; + calc_type g = (rgb >> 4) & 0xFFC0; + calc_type b = (rgb << 6) & 0xFFC0; + *p = (pixel_type) + ((((r * alpha + cr * cover) >> 2) & 0x3FF00000) | + (((g * alpha + cg * cover) >> 12) & 0x000FFC00) | + ((b * alpha + cb * cover) >> 22) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (b >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 14) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p << 6) & 0xFFC0); + } + }; + + + + //=================================================blender_rgbAAA_gamma + template class blender_rgbAAA_gamma + { + public: + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + typedef Gamma gamma_type; + + blender_rgbAAA_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = m_gamma->dir((rgb >> 14) & 0xFFC0); + calc_type g = m_gamma->dir((rgb >> 4) & 0xFFC0); + calc_type b = m_gamma->dir((rgb << 6) & 0xFFC0); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 14) & 0x3FF00000) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) | + (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (b >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 14) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p << 6) & 0xFFC0); + } + private: + const Gamma* m_gamma; + }; + + + //=====================================================blender_bgrAAA + struct blender_bgrAAA + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type bgr = *p; + calc_type b = (bgr >> 14) & 0xFFC0; + calc_type g = (bgr >> 4) & 0xFFC0; + calc_type r = (bgr << 6) & 0xFFC0; + *p = (pixel_type) + (((((cb - b) * alpha + (b << 16)) >> 2) & 0x3FF00000) | + ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) | + (((cr - r) * alpha + (r << 16)) >> 22) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (r >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 6) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p >> 14) & 0xFFC0); + } + }; + + + + //=================================================blender_bgrAAA_pre + struct blender_bgrAAA_pre + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + cover = (cover + 1) << (color_type::base_shift - 8); + pixel_type bgr = *p; + calc_type b = (bgr >> 14) & 0xFFC0; + calc_type g = (bgr >> 4) & 0xFFC0; + calc_type r = (bgr << 6) & 0xFFC0; + *p = (pixel_type) + ((((b * alpha + cb * cover) >> 2) & 0x3FF00000) | + (((g * alpha + cg * cover) >> 12) & 0x000FFC00) | + ((r * alpha + cr * cover) >> 22) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (r >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 6) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p >> 14) & 0xFFC0); + } + }; + + + + //=================================================blender_bgrAAA_gamma + template class blender_bgrAAA_gamma + { + public: + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + typedef Gamma gamma_type; + + blender_bgrAAA_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type bgr = *p; + calc_type b = m_gamma->dir((bgr >> 14) & 0xFFC0); + calc_type g = m_gamma->dir((bgr >> 4) & 0xFFC0); + calc_type r = m_gamma->dir((bgr << 6) & 0xFFC0); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 14) & 0x3FF00000) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) | + (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 6 ) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (r >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 6) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p >> 14) & 0xFFC0); + } + + private: + const Gamma* m_gamma; + }; + + + + //=====================================================blender_rgbBBA + struct blender_rgbBBA + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = (rgb >> 16) & 0xFFE0; + calc_type g = (rgb >> 5) & 0xFFE0; + calc_type b = (rgb << 6) & 0xFFC0; + *p = (pixel_type) + (((((cr - r) * alpha + (r << 16)) ) & 0xFFE00000) | + ((((cg - g) * alpha + (g << 16)) >> 11) & 0x001FFC00) | + (((cb - b) * alpha + (b << 16)) >> 22)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 16) & 0xFFE0, + (p >> 5) & 0xFFE0, + (p << 6) & 0xFFC0); + } + }; + + + //=================================================blender_rgbBBA_pre + struct blender_rgbBBA_pre + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + cover = (cover + 1) << (color_type::base_shift - 8); + pixel_type rgb = *p; + calc_type r = (rgb >> 16) & 0xFFE0; + calc_type g = (rgb >> 5) & 0xFFE0; + calc_type b = (rgb << 6) & 0xFFC0; + *p = (pixel_type) + ((((r * alpha + cr * cover) ) & 0xFFE00000) | + (((g * alpha + cg * cover) >> 11) & 0x001FFC00) | + ((b * alpha + cb * cover) >> 22)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 16) & 0xFFE0, + (p >> 5) & 0xFFE0, + (p << 6) & 0xFFC0); + } + }; + + + + //=================================================blender_rgbBBA_gamma + template class blender_rgbBBA_gamma + { + public: + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + typedef Gamma gamma_type; + + blender_rgbBBA_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = m_gamma->dir((rgb >> 16) & 0xFFE0); + calc_type g = m_gamma->dir((rgb >> 5) & 0xFFE0); + calc_type b = m_gamma->dir((rgb << 6) & 0xFFC0); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 16) & 0xFFE00000) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 5 ) & 0x001FFC00) | + (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 )); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 16) & 0xFFE0, + (p >> 5) & 0xFFE0, + (p << 6) & 0xFFC0); + } + + private: + const Gamma* m_gamma; + }; + + + //=====================================================blender_bgrABB + struct blender_bgrABB + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type bgr = *p; + calc_type b = (bgr >> 16) & 0xFFC0; + calc_type g = (bgr >> 6) & 0xFFE0; + calc_type r = (bgr << 5) & 0xFFE0; + *p = (pixel_type) + (((((cb - b) * alpha + (b << 16)) ) & 0xFFC00000) | + ((((cg - g) * alpha + (g << 16)) >> 10) & 0x003FF800) | + (((cr - r) * alpha + (r << 16)) >> 21)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 5) & 0xFFE0, + (p >> 6) & 0xFFE0, + (p >> 16) & 0xFFC0); + } + }; + + + //=================================================blender_bgrABB_pre + struct blender_bgrABB_pre + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + cover = (cover + 1) << (color_type::base_shift - 8); + pixel_type bgr = *p; + calc_type b = (bgr >> 16) & 0xFFC0; + calc_type g = (bgr >> 6) & 0xFFE0; + calc_type r = (bgr << 5) & 0xFFE0; + *p = (pixel_type) + ((((b * alpha + cb * cover) ) & 0xFFC00000) | + (((g * alpha + cg * cover) >> 10) & 0x003FF800) | + ((r * alpha + cr * cover) >> 21)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 5) & 0xFFE0, + (p >> 6) & 0xFFE0, + (p >> 16) & 0xFFC0); + } + }; + + + + //=================================================blender_bgrABB_gamma + template class blender_bgrABB_gamma + { + public: + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + typedef Gamma gamma_type; + + blender_bgrABB_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type bgr = *p; + calc_type b = m_gamma->dir((bgr >> 16) & 0xFFC0); + calc_type g = m_gamma->dir((bgr >> 6) & 0xFFE0); + calc_type r = m_gamma->dir((bgr << 5) & 0xFFE0); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 16) & 0xFFC00000) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 6 ) & 0x003FF800) | + (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 5 )); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 5) & 0xFFE0, + (p >> 6) & 0xFFE0, + (p >> 16) & 0xFFC0); + } + + private: + const Gamma* m_gamma; + }; + + + + //===========================================pixfmt_alpha_blend_rgb_packed + template class pixfmt_alpha_blend_rgb_packed + { + 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 typename blender_type::pixel_type pixel_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(pixel_type) + }; + + private: + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_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 = m_blender.make_pix(c.r, c.g, c.b); + } + else + { + m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); + } + } + } + + public: + //-------------------------------------------------------------------- + pixfmt_alpha_blend_rgb_packed(rbuf_type& rb) : m_rbuf(&rb) {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + template + 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 void make_pix(int8u* p, const color_type& c) + { + *(pixel_type*)p = m_blender.make_pix(c.r, c.g, c.b); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + return m_blender.make_color(((pixel_type*)m_rbuf->row_ptr(y))[x]); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + ((pixel_type*) + m_rbuf->row_ptr(x, y, 1))[x] = + m_blender.make_pix(c.r, c.g, c.b); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y, 1) + x, c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + pixel_type v = m_blender.make_pix(c.r, c.g, c.b); + do + { + *p++ = v; + } + while(--len); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v = m_blender.make_pix(c.r, c.g, c.b); + do + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x; + *p = v; + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (c.a) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; + if(alpha == base_mask) + { + pixel_type v = m_blender.make_pix(c.r, c.g, c.b); + do + { + *p++ = v; + } + while(--len); + } + else + { + do + { + m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); + ++p; + } + while(--len); + } + } + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (c.a) + { + calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; + if(alpha == base_mask) + { + pixel_type v = m_blender.make_pix(c.r, c.g, c.b); + do + { + ((pixel_type*)m_rbuf->row_ptr(x, y++, 1))[x] = v; + } + while(--len); + } + else + { + do + { + m_blender.blend_pix( + (pixel_type*)m_rbuf->row_ptr(x, y++, 1), + 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) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + do + { + copy_or_blend_pix(p, c, *covers++); + ++p; + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + do + { + copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x, + c, *covers++); + } + while(--len); + } + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + do + { + *p++ = m_blender.make_pix(colors->r, colors->g, colors->b); + ++colors; + } + while(--len); + } + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x; + *p = m_blender.make_pix(colors->r, colors->g, colors->b); + ++colors; + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + do + { + copy_or_blend_pix(p++, *colors++, covers ? *covers++ : cover); + } + 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((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x, + *colors++, covers ? *covers++ : cover); + } + while(--len); + } + + //-------------------------------------------------------------------- + template + 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 + 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; + pixel_type* pdst = + (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst; + do + { + value_type alpha = psrc[src_order::A]; + if(alpha) + { + if(alpha == base_mask && cover == 255) + { + *pdst = m_blender.make_pix(psrc[src_order::R], + psrc[src_order::G], + psrc[src_order::B]); + } + else + { + m_blender.blend_pix(pdst, + psrc[src_order::R], + psrc[src_order::G], + psrc[src_order::B], + alpha, + cover); + } + } + psrc += 4; + ++pdst; + } + while(--len); + } + } + + private: + rbuf_type* m_rbuf; + Blender m_blender; + }; + + typedef pixfmt_alpha_blend_rgb_packed pixfmt_rgb555; //----pixfmt_rgb555 + typedef pixfmt_alpha_blend_rgb_packed pixfmt_rgb565; //----pixfmt_rgb565 + + typedef pixfmt_alpha_blend_rgb_packed pixfmt_rgb555_pre; //----pixfmt_rgb555_pre + typedef pixfmt_alpha_blend_rgb_packed pixfmt_rgb565_pre; //----pixfmt_rgb565_pre + + typedef pixfmt_alpha_blend_rgb_packed pixfmt_rgbAAA; //----pixfmt_rgbAAA + typedef pixfmt_alpha_blend_rgb_packed pixfmt_bgrAAA; //----pixfmt_bgrAAA + typedef pixfmt_alpha_blend_rgb_packed pixfmt_rgbBBA; //----pixfmt_rgbBBA + typedef pixfmt_alpha_blend_rgb_packed pixfmt_bgrABB; //----pixfmt_bgrABB + + typedef pixfmt_alpha_blend_rgb_packed pixfmt_rgbAAA_pre; //----pixfmt_rgbAAA_pre + typedef pixfmt_alpha_blend_rgb_packed pixfmt_bgrAAA_pre; //----pixfmt_bgrAAA_pre + typedef pixfmt_alpha_blend_rgb_packed pixfmt_rgbBBA_pre; //----pixfmt_rgbBBA_pre + typedef pixfmt_alpha_blend_rgb_packed pixfmt_bgrABB_pre; //----pixfmt_bgrABB_pre + + + //-----------------------------------------------------pixfmt_rgb555_gamma + template class pixfmt_rgb555_gamma : + public pixfmt_alpha_blend_rgb_packed, + rendering_buffer> + { + public: + pixfmt_rgb555_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_rgb565_gamma + template class pixfmt_rgb565_gamma : + public pixfmt_alpha_blend_rgb_packed, rendering_buffer> + { + public: + pixfmt_rgb565_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed, rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_rgbAAA_gamma + template class pixfmt_rgbAAA_gamma : + public pixfmt_alpha_blend_rgb_packed, + rendering_buffer> + { + public: + pixfmt_rgbAAA_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_bgrAAA_gamma + template class pixfmt_bgrAAA_gamma : + public pixfmt_alpha_blend_rgb_packed, + rendering_buffer> + { + public: + pixfmt_bgrAAA_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_rgbBBA_gamma + template class pixfmt_rgbBBA_gamma : + public pixfmt_alpha_blend_rgb_packed, + rendering_buffer> + { + public: + pixfmt_rgbBBA_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_bgrABB_gamma + template class pixfmt_bgrABB_gamma : + public pixfmt_alpha_blend_rgb_packed, + rendering_buffer> + { + public: + pixfmt_bgrABB_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + +} + +#endif + diff --git a/headers/libs/agg/agg_pixfmt_rgba.h b/headers/libs/agg/agg_pixfmt_rgba.h new file mode 100644 index 0000000000..20ec1299ff --- /dev/null +++ b/headers/libs/agg/agg_pixfmt_rgba.h @@ -0,0 +1,2774 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_RGBA_INCLUDED +#define AGG_PIXFMT_RGBA_INCLUDED + +#include +#include +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + + //=========================================================multiplier_rgba + template struct multiplier_rgba + { + typedef typename ColorT::value_type value_type; + typedef typename ColorT::calc_type calc_type; + + //-------------------------------------------------------------------- + static AGG_INLINE void premultiply(value_type* p) + { + calc_type a = p[Order::A]; + if(a < ColorT::base_mask) + { + if(a == 0) + { + p[Order::R] = p[Order::G] = p[Order::B] = 0; + return; + } + p[Order::R] = value_type((p[Order::R] * a + ColorT::base_mask) >> ColorT::base_shift); + p[Order::G] = value_type((p[Order::G] * a + ColorT::base_mask) >> ColorT::base_shift); + p[Order::B] = value_type((p[Order::B] * a + ColorT::base_mask) >> ColorT::base_shift); + } + } + + + //-------------------------------------------------------------------- + static AGG_INLINE void demultiply(value_type* p) + { + calc_type a = p[Order::A]; + if(a < ColorT::base_mask) + { + if(a == 0) + { + p[Order::R] = p[Order::G] = p[Order::B] = 0; + return; + } + calc_type r = (calc_type(p[Order::R]) * ColorT::base_mask) / a; + calc_type g = (calc_type(p[Order::G]) * ColorT::base_mask) / a; + calc_type b = (calc_type(p[Order::B]) * ColorT::base_mask) / a; + p[Order::R] = value_type((r > ColorT::base_mask) ? ColorT::base_mask : r); + p[Order::G] = value_type((g > ColorT::base_mask) ? ColorT::base_mask : g); + p[Order::B] = value_type((b > ColorT::base_mask) ? ColorT::base_mask : b); + } + } + }; + + //=====================================================apply_gamma_dir_rgba + template class apply_gamma_dir_rgba + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_dir_rgba(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_rgba + template class apply_gamma_inv_rgba + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_inv_rgba(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_rgba + template struct blender_rgba + { + 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, + base_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover=0) + { + calc_type r = p[Order::R]; + calc_type g = p[Order::G]; + calc_type b = p[Order::B]; + calc_type a = p[Order::A]; + p[Order::R] = (value_type)(((cr - r) * alpha + (r << base_shift)) >> base_shift); + p[Order::G] = (value_type)(((cg - g) * alpha + (g << base_shift)) >> base_shift); + p[Order::B] = (value_type)(((cb - b) * alpha + (b << base_shift)) >> base_shift); + p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift)); + } + }; + + //=========================================================blender_rgba_pre + template struct blender_rgba_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, + base_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + 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); + p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> 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); + p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift)); + } + }; + + //======================================================blender_rgba_plain + template struct blender_rgba_plain + { + 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) + { + if(alpha == 0) return; + calc_type a = p[Order::A]; + calc_type r = p[Order::R] * a; + calc_type g = p[Order::G] * a; + calc_type b = p[Order::B] * a; + a = ((alpha + a) << base_shift) - alpha * a; + p[Order::A] = (value_type)(a >> base_shift); + p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a); + p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a); + p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a); + } + }; + + + + + + + + + + + + //=========================================================comp_op_rgba_clear + template struct comp_op_rgba_clear + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(value_type* p, + unsigned, unsigned, unsigned, unsigned, + unsigned cover) + { + if(cover < 255) + { + cover = 255 - cover; + p[Order::R] = (value_type)((p[Order::R] * cover + 255) >> 8); + p[Order::G] = (value_type)((p[Order::G] * cover + 255) >> 8); + p[Order::B] = (value_type)((p[Order::B] * cover + 255) >> 8); + p[Order::A] = (value_type)((p[Order::A] * cover + 255) >> 8); + } + else + { + p[0] = p[1] = p[2] = p[3] = 0; + } + } + }; + + //===========================================================comp_op_rgba_src + template struct comp_op_rgba_src + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + unsigned alpha = 255 - cover; + p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((sr * cover + 255) >> 8)); + p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((sg * cover + 255) >> 8)); + p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((sb * cover + 255) >> 8)); + p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((sa * cover + 255) >> 8)); + } + else + { + p[Order::R] = sr; + p[Order::G] = sg; + p[Order::B] = sb; + p[Order::A] = sa; + } + } + }; + + //===========================================================comp_op_rgba_dst + template struct comp_op_rgba_dst + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + + static AGG_INLINE void blend_pix(value_type*, + unsigned, unsigned, unsigned, + unsigned, unsigned) + { + } + }; + + //======================================================comp_op_rgba_src_over + template struct comp_op_rgba_src_over + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Sca + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + calc_type s1a = base_mask - sa; + p[Order::R] = (value_type)(sr + ((p[Order::R] * s1a + base_mask) >> base_shift)); + p[Order::G] = (value_type)(sg + ((p[Order::G] * s1a + base_mask) >> base_shift)); + p[Order::B] = (value_type)(sb + ((p[Order::B] * s1a + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } + }; + + //======================================================comp_op_rgba_dst_over + template struct comp_op_rgba_dst_over + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Dca + Sca.(1 - Da) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + calc_type d1a = base_mask - p[Order::A]; + p[Order::R] = (value_type)(p[Order::R] + ((sr * d1a + base_mask) >> base_shift)); + p[Order::G] = (value_type)(p[Order::G] + ((sg * d1a + base_mask) >> base_shift)); + p[Order::B] = (value_type)(p[Order::B] + ((sb * d1a + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } + }; + + //======================================================comp_op_rgba_src_in + template struct comp_op_rgba_src_in + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Sca.Da + // Da' = Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + calc_type da = p[Order::A]; + if(cover < 255) + { + unsigned alpha = 255 - cover; + p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((((sr * da + base_mask) >> base_shift) * cover + 255) >> 8)); + p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((((sg * da + base_mask) >> base_shift) * cover + 255) >> 8)); + p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((((sb * da + base_mask) >> base_shift) * cover + 255) >> 8)); + p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((((sa * da + base_mask) >> base_shift) * cover + 255) >> 8)); + } + else + { + p[Order::R] = (value_type)((sr * da + base_mask) >> base_shift); + p[Order::G] = (value_type)((sg * da + base_mask) >> base_shift); + p[Order::B] = (value_type)((sb * da + base_mask) >> base_shift); + p[Order::A] = (value_type)((sa * da + base_mask) >> base_shift); + } + } + }; + + //======================================================comp_op_rgba_dst_in + template struct comp_op_rgba_dst_in + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Dca.Sa + // Da' = Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned, unsigned, unsigned, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sa = base_mask - ((cover * (base_mask - sa) + 255) >> 8); + } + p[Order::R] = (value_type)((p[Order::R] * sa + base_mask) >> base_shift); + p[Order::G] = (value_type)((p[Order::G] * sa + base_mask) >> base_shift); + p[Order::B] = (value_type)((p[Order::B] * sa + base_mask) >> base_shift); + p[Order::A] = (value_type)((p[Order::A] * sa + base_mask) >> base_shift); + } + }; + + //======================================================comp_op_rgba_src_out + template struct comp_op_rgba_src_out + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Sca.(1 - Da) + // Da' = Sa.(1 - Da) + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + calc_type da = base_mask - p[Order::A]; + if(cover < 255) + { + unsigned alpha = 255 - cover; + p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((((sr * da + base_mask) >> base_shift) * cover + 255) >> 8)); + p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((((sg * da + base_mask) >> base_shift) * cover + 255) >> 8)); + p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((((sb * da + base_mask) >> base_shift) * cover + 255) >> 8)); + p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((((sa * da + base_mask) >> base_shift) * cover + 255) >> 8)); + } + else + { + p[Order::R] = (value_type)((sr * da + base_mask) >> base_shift); + p[Order::G] = (value_type)((sg * da + base_mask) >> base_shift); + p[Order::B] = (value_type)((sb * da + base_mask) >> base_shift); + p[Order::A] = (value_type)((sa * da + base_mask) >> base_shift); + } + } + }; + + //======================================================comp_op_rgba_dst_out + template struct comp_op_rgba_dst_out + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Dca.(1 - Sa) + // Da' = Da.(1 - Sa) + static AGG_INLINE void blend_pix(value_type* p, + unsigned, unsigned, unsigned, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sa = (sa * cover + 255) >> 8; + } + sa = base_mask - sa; + p[Order::R] = (value_type)((p[Order::R] * sa + base_shift) >> base_shift); + p[Order::G] = (value_type)((p[Order::G] * sa + base_shift) >> base_shift); + p[Order::B] = (value_type)((p[Order::B] * sa + base_shift) >> base_shift); + p[Order::A] = (value_type)((p[Order::A] * sa + base_shift) >> base_shift); + } + }; + + //=====================================================comp_op_rgba_src_atop + template struct comp_op_rgba_src_atop + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Sca.Da + Dca.(1 - Sa) + // Da' = Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + calc_type da = p[Order::A]; + sa = base_mask - sa; + p[Order::R] = (value_type)((sr * da + p[Order::R] * sa + base_mask) >> base_shift); + p[Order::G] = (value_type)((sg * da + p[Order::G] * sa + base_mask) >> base_shift); + p[Order::B] = (value_type)((sb * da + p[Order::B] * sa + base_mask) >> base_shift); + } + }; + + //=====================================================comp_op_rgba_dst_atop + template struct comp_op_rgba_dst_atop + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Dca.Sa + Sca.(1 - Da) + // Da' = Sa + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + calc_type da = base_mask - p[Order::A]; + if(cover < 255) + { + unsigned alpha = 255 - cover; + sr = (p[Order::R] * sa + sr * da + base_mask) >> base_shift; + sg = (p[Order::G] * sa + sg * da + base_mask) >> base_shift; + sb = (p[Order::B] * sa + sb * da + base_mask) >> base_shift; + p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((sr * cover + 255) >> 8)); + p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((sg * cover + 255) >> 8)); + p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((sb * cover + 255) >> 8)); + p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((sa * cover + 255) >> 8)); + + } + else + { + p[Order::R] = (value_type)((p[Order::R] * sa + sr * da + base_mask) >> base_shift); + p[Order::G] = (value_type)((p[Order::G] * sa + sg * da + base_mask) >> base_shift); + p[Order::B] = (value_type)((p[Order::B] * sa + sb * da + base_mask) >> base_shift); + p[Order::A] = (value_type)sa; + } + } + }; + + //=========================================================comp_op_rgba_xor + template struct comp_op_rgba_xor + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - 2.Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type s1a = base_mask - sa; + calc_type d1a = base_mask - p[Order::A]; + p[Order::R] = (value_type)((p[Order::R] * s1a + sr * d1a + base_mask) >> base_shift); + p[Order::G] = (value_type)((p[Order::G] * s1a + sg * d1a + base_mask) >> base_shift); + p[Order::B] = (value_type)((p[Order::B] * s1a + sb * d1a + base_mask) >> base_shift); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask/2) >> (base_shift - 1))); + } + } + }; + + //=========================================================comp_op_rgba_plus + template struct comp_op_rgba_plus + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Sca + Dca + // Da' = Sa + Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type dr = p[Order::R] + sr; + calc_type dg = p[Order::G] + sg; + calc_type db = p[Order::B] + sb; + calc_type da = p[Order::A] + sa; + p[Order::R] = (dr > base_mask) ? base_mask : dr; + p[Order::G] = (dg > base_mask) ? base_mask : dg; + p[Order::B] = (db > base_mask) ? base_mask : db; + p[Order::A] = (da > base_mask) ? base_mask : da; + } + } + }; + + //========================================================comp_op_rgba_minus + template struct comp_op_rgba_minus + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Dca - Sca + // Da' = 1 - (1 - Sa).(1 - Da) + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type dr = p[Order::R] - sr; + calc_type dg = p[Order::G] - sg; + calc_type db = p[Order::B] - sb; + p[Order::R] = (dr > base_mask) ? 0 : dr; + p[Order::G] = (dg > base_mask) ? 0 : dg; + p[Order::B] = (db > base_mask) ? 0 : db; + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + //p[Order::A] = (value_type)(base_mask - (((base_mask - sa) * (base_mask - p[Order::A]) + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_multiply + template struct comp_op_rgba_multiply + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type s1a = base_mask - sa; + calc_type d1a = base_mask - p[Order::A]; + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + p[Order::R] = (value_type)((sr * dr + sr * d1a + dr * s1a + base_mask) >> base_shift); + p[Order::G] = (value_type)((sg * dg + sg * d1a + dg * s1a + base_mask) >> base_shift); + p[Order::B] = (value_type)((sb * db + sb * d1a + db * s1a + base_mask) >> base_shift); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_screen + template struct comp_op_rgba_screen + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = Sca + Dca - Sca.Dca + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + calc_type da = p[Order::A]; + p[Order::R] = (value_type)(sr + dr - ((sr * dr + base_mask) >> base_shift)); + p[Order::G] = (value_type)(sg + dg - ((sg * dg + base_mask) >> base_shift)); + p[Order::B] = (value_type)(sb + db - ((sb * db + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_overlay + template struct comp_op_rgba_overlay + { + 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, + base_mask = color_type::base_mask + }; + + // if 2.Dca < Da + // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise + // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type d1a = base_mask - p[Order::A]; + calc_type s1a = base_mask - sa; + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + calc_type da = p[Order::A]; + calc_type sada = sa * p[Order::A]; + + p[Order::R] = (value_type)(((2*dr < da) ? + 2*sr*dr + sr*d1a + dr*s1a : + sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift); + + p[Order::G] = (value_type)(((2*dg < da) ? + 2*sg*dg + sg*d1a + dg*s1a : + sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift); + + p[Order::B] = (value_type)(((2*db < da) ? + 2*sb*db + sb*d1a + db*s1a : + sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift); + + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + + template inline T sd_min(T a, T b) { return (a < b) ? a : b; } + template inline T sd_max(T a, T b) { return (a > b) ? a : b; } + + //=====================================================comp_op_rgba_darken + template struct comp_op_rgba_darken + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type d1a = base_mask - p[Order::A]; + calc_type s1a = base_mask - sa; + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + calc_type da = p[Order::A]; + + p[Order::R] = (value_type)((sd_min(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift); + p[Order::G] = (value_type)((sd_min(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift); + p[Order::B] = (value_type)((sd_min(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_lighten + template struct comp_op_rgba_lighten + { + 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, + base_mask = color_type::base_mask + }; + + // Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type d1a = base_mask - p[Order::A]; + calc_type s1a = base_mask - sa; + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + calc_type da = p[Order::A]; + + p[Order::R] = (value_type)((sd_max(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift); + p[Order::G] = (value_type)((sd_max(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift); + p[Order::B] = (value_type)((sd_max(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_color_dodge + template struct comp_op_rgba_color_dodge + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // if Sca.Da + Dca.Sa >= Sa.Da + // Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise + // Dca' = Dca.Sa/(1-Sca/Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type d1a = base_mask - p[Order::A]; + calc_type s1a = base_mask - sa; + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + calc_type da = p[Order::A]; + long_type drsa = dr * sa; + long_type dgsa = dg * sa; + long_type dbsa = db * sa; + long_type srda = sr * da; + long_type sgda = sg * da; + long_type sbda = sb * da; + long_type sada = sa * da; + + p[Order::R] = (value_type)((srda + drsa >= sada) ? + (sada + sr * d1a + dr * s1a + base_mask) >> base_shift : + drsa / (base_mask - (sr << base_shift) / sa) + ((sr * d1a + dr * s1a + base_mask) >> base_shift)); + + p[Order::G] = (value_type)((sgda + dgsa >= sada) ? + (sada + sg * d1a + dg * s1a + base_mask) >> base_shift : + dgsa / (base_mask - (sg << base_shift) / sa) + ((sg * d1a + dg * s1a + base_mask) >> base_shift)); + + p[Order::B] = (value_type)((sbda + dbsa >= sada) ? + (sada + sb * d1a + db * s1a + base_mask) >> base_shift : + dbsa / (base_mask - (sb << base_shift) / sa) + ((sb * d1a + db * s1a + base_mask) >> base_shift)); + + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_color_burn + template struct comp_op_rgba_color_burn + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // if Sca.Da + Dca.Sa <= Sa.Da + // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise + // Dca' = Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type d1a = base_mask - p[Order::A]; + calc_type s1a = base_mask - sa; + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + calc_type da = p[Order::A]; + long_type drsa = dr * sa; + long_type dgsa = dg * sa; + long_type dbsa = db * sa; + long_type srda = sr * da; + long_type sgda = sg * da; + long_type sbda = sb * da; + long_type sada = sa * da; + + p[Order::R] = (value_type)(((srda + drsa <= sada) ? + sr * d1a + dr * s1a : + sa * (srda + drsa - sada) / sr + sr * d1a + dr * s1a + base_mask) >> base_shift); + + p[Order::G] = (value_type)(((sgda + dgsa <= sada) ? + sg * d1a + dg * s1a : + sa * (sgda + dgsa - sada) / sg + sg * d1a + dg * s1a + base_mask) >> base_shift); + + p[Order::B] = (value_type)(((sbda + dbsa <= sada) ? + sb * d1a + db * s1a : + sa * (sbda + dbsa - sada) / sb + sb * d1a + db * s1a + base_mask) >> base_shift); + + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_hard_light + template struct comp_op_rgba_hard_light + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // if 2.Sca < Sa + // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise + // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type d1a = base_mask - p[Order::A]; + calc_type s1a = base_mask - sa; + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + calc_type da = p[Order::A]; + calc_type sada = sa * da; + + p[Order::R] = (value_type)(((2*sr < sa) ? + 2*sr*dr + sr*d1a + dr*s1a : + sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift); + + p[Order::G] = (value_type)(((2*sg < sa) ? + 2*sg*dg + sg*d1a + dg*s1a : + sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift); + + p[Order::B] = (value_type)(((2*sb < sa) ? + 2*sb*db + sb*d1a + db*s1a : + sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift); + + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_soft_light + template struct comp_op_rgba_soft_light + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // if 2.Sca < Sa + // Dca' = Dca.(Sa + (1 - Dca/Da).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if 8.Dca <= Da + // Dca' = Dca.(Sa + (1 - Dca/Da).(2.Sca - Sa).(3 - 8.Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise + // Dca' = (Dca.Sa + ((Dca/Da)^(0.5).Da - Dca).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + + static AGG_INLINE void blend_pix(value_type* p, + unsigned r, unsigned g, unsigned b, + unsigned a, unsigned cover) + { + double sr = double(r * cover) / (base_mask * 255); + double sg = double(g * cover) / (base_mask * 255); + double sb = double(b * cover) / (base_mask * 255); + double sa = double(a * cover) / (base_mask * 255); + if(sa > 0) + { + double dr = double(p[Order::R]) / base_mask; + double dg = double(p[Order::G]) / base_mask; + double db = double(p[Order::B]) / base_mask; + double da = double(p[Order::A] ? p[Order::A] : 1) / base_mask; + if(cover < 255) + { + a = (a * cover + 255) >> 8; + } + + if(2*sr < sa) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa); + else if(8*dr <= da) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)*(3 - 8*dr/da)) + sr*(1 - da) + dr*(1 - sa); + else dr = (dr*sa + (sqrt(dr/da)*da - dr)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa); + + if(2*sg < sa) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa); + else if(8*dg <= da) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)*(3 - 8*dg/da)) + sg*(1 - da) + dg*(1 - sa); + else dg = (dg*sa + (sqrt(dg/da)*da - dg)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa); + + if(2*sb < sa) db = db*(sa + (1 - db/da)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa); + else if(8*db <= da) db = db*(sa + (1 - db/da)*(2*sb - sa)*(3 - 8*db/da)) + sb*(1 - da) + db*(1 - sa); + else db = (db*sa + (sqrt(db/da)*da - db)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa); + + p[Order::R] = (value_type)uround(dr * base_mask); + p[Order::G] = (value_type)uround(dg * base_mask); + p[Order::B] = (value_type)uround(db * base_mask); + p[Order::A] = (value_type)(a + p[Order::A] - ((a * p[Order::A] + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_difference + template struct comp_op_rgba_difference + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_scale = color_type::base_scale, + base_mask = color_type::base_mask + }; + + // Dca' = Sca + Dca - 2.min(Sca.Da, Dca.Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + calc_type da = p[Order::A]; + p[Order::R] = (value_type)(sr + dr - ((2 * sd_min(sr*da, dr*sa) + base_mask) >> base_shift)); + p[Order::G] = (value_type)(sg + dg - ((2 * sd_min(sg*da, dg*sa) + base_mask) >> base_shift)); + p[Order::B] = (value_type)(sb + db - ((2 * sd_min(sb*da, db*sa) + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_exclusion + template struct comp_op_rgba_exclusion + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type d1a = base_mask - p[Order::A]; + calc_type s1a = base_mask - sa; + calc_type dr = p[Order::R]; + calc_type dg = p[Order::G]; + calc_type db = p[Order::B]; + calc_type da = p[Order::A]; + p[Order::R] = (value_type)((sr*da + dr*sa - 2*sr*dr + sr*d1a + dr*s1a + base_mask) >> base_shift); + p[Order::G] = (value_type)((sg*da + dg*sa - 2*sg*dg + sg*d1a + dg*s1a + base_mask) >> base_shift); + p[Order::B] = (value_type)((sb*da + db*sa - 2*sb*db + sb*d1a + db*s1a + base_mask) >> base_shift); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=====================================================comp_op_rgba_contrast + template struct comp_op_rgba_contrast + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + long_type dr = p[Order::R]; + long_type dg = p[Order::G]; + long_type db = p[Order::B]; + int da = p[Order::A]; + long_type d2a = da >> 1; + unsigned s2a = sa >> 1; + + int r = (int)((((dr - d2a) * int((sr - s2a)*2 + base_mask)) >> base_shift) + d2a); + int g = (int)((((dg - d2a) * int((sg - s2a)*2 + base_mask)) >> base_shift) + d2a); + int b = (int)((((db - d2a) * int((sb - s2a)*2 + base_mask)) >> base_shift) + d2a); + + r = (r < 0) ? 0 : r; + g = (g < 0) ? 0 : g; + b = (b < 0) ? 0 : b; + + p[Order::R] = (value_type)((r > da) ? da : r); + p[Order::G] = (value_type)((g > da) ? da : g); + p[Order::B] = (value_type)((b > da) ? da : b); + } + }; + + //=====================================================comp_op_rgba_invert + template struct comp_op_rgba_invert + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // Dca' = (Da - Dca) * Sa + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + sa = (sa * cover + 255) >> 8; + if(sa) + { + calc_type da = p[Order::A]; + calc_type dr = ((da - p[Order::R]) * sa + base_mask) >> base_shift; + calc_type dg = ((da - p[Order::G]) * sa + base_mask) >> base_shift; + calc_type db = ((da - p[Order::B]) * sa + base_mask) >> base_shift; + calc_type s1a = base_mask - sa; + p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift)); + p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift)); + p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=================================================comp_op_rgba_invert_rgb + template struct comp_op_rgba_invert_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; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // Dca' = (Da - Dca) * Sca + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if(cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if(sa) + { + calc_type da = p[Order::A]; + calc_type dr = ((da - p[Order::R]) * sr + base_mask) >> base_shift; + calc_type dg = ((da - p[Order::G]) * sg + base_mask) >> base_shift; + calc_type db = ((da - p[Order::B]) * sb + base_mask) >> base_shift; + calc_type s1a = base_mask - sa; + p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift)); + p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift)); + p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + + + + + //======================================================comp_op_table_rgba + template struct comp_op_table_rgba + { + typedef typename ColorT::value_type value_type; + typedef void (*comp_op_func_type)(value_type* p, + unsigned cr, + unsigned cg, + unsigned cb, + unsigned ca, + unsigned cover); + static comp_op_func_type g_comp_op_func[]; + }; + + //==========================================================g_comp_op_func + template + typename comp_op_table_rgba::comp_op_func_type + comp_op_table_rgba::g_comp_op_func[] = + { + comp_op_rgba_clear ::blend_pix, + comp_op_rgba_src ::blend_pix, + comp_op_rgba_dst ::blend_pix, + comp_op_rgba_src_over ::blend_pix, + comp_op_rgba_dst_over ::blend_pix, + comp_op_rgba_src_in ::blend_pix, + comp_op_rgba_dst_in ::blend_pix, + comp_op_rgba_src_out ::blend_pix, + comp_op_rgba_dst_out ::blend_pix, + comp_op_rgba_src_atop ::blend_pix, + comp_op_rgba_dst_atop ::blend_pix, + comp_op_rgba_xor ::blend_pix, + comp_op_rgba_plus ::blend_pix, + comp_op_rgba_minus ::blend_pix, + comp_op_rgba_multiply ::blend_pix, + comp_op_rgba_screen ::blend_pix, + comp_op_rgba_overlay ::blend_pix, + comp_op_rgba_darken ::blend_pix, + comp_op_rgba_lighten ::blend_pix, + comp_op_rgba_color_dodge::blend_pix, + comp_op_rgba_color_burn ::blend_pix, + comp_op_rgba_hard_light ::blend_pix, + comp_op_rgba_soft_light ::blend_pix, + comp_op_rgba_difference ::blend_pix, + comp_op_rgba_exclusion ::blend_pix, + comp_op_rgba_contrast ::blend_pix, + comp_op_rgba_invert ::blend_pix, + comp_op_rgba_invert_rgb ::blend_pix, + 0 + }; + + + //==============================================================comp_op_e + enum comp_op_e + { + comp_op_clear, //----comp_op_clear + comp_op_src, //----comp_op_src + comp_op_dst, //----comp_op_dst + comp_op_src_over, //----comp_op_src_over + comp_op_dst_over, //----comp_op_dst_over + comp_op_src_in, //----comp_op_src_in + comp_op_dst_in, //----comp_op_dst_in + comp_op_src_out, //----comp_op_src_out + comp_op_dst_out, //----comp_op_dst_out + comp_op_src_atop, //----comp_op_src_atop + comp_op_dst_atop, //----comp_op_dst_atop + comp_op_xor, //----comp_op_xor + comp_op_plus, //----comp_op_plus + comp_op_minus, //----comp_op_minus + comp_op_multiply, //----comp_op_multiply + comp_op_screen, //----comp_op_screen + comp_op_overlay, //----comp_op_overlay + comp_op_darken, //----comp_op_darken + comp_op_lighten, //----comp_op_lighten + comp_op_color_dodge, //----comp_op_color_dodge + comp_op_color_burn, //----comp_op_color_burn + comp_op_hard_light, //----comp_op_hard_light + comp_op_soft_light, //----comp_op_soft_light + comp_op_difference, //----comp_op_difference + comp_op_exclusion, //----comp_op_exclusion + comp_op_contrast, //----comp_op_contrast + comp_op_invert, //----comp_op_invert + comp_op_invert_rgb, //----comp_op_invert_rgb + + end_of_comp_op_e + }; + + + + + + + + //====================================================comp_op_adaptor_rgba + template struct comp_op_adaptor_rgba + { + typedef Order order_type; + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned ca, + unsigned cover) + { + comp_op_table_rgba::g_comp_op_func[op] + (p, (cr * ca + base_mask) >> base_shift, + (cg * ca + base_mask) >> base_shift, + (cb * ca + base_mask) >> base_shift, + ca, cover); + } + }; + + //=========================================comp_op_adaptor_clip_to_dst_rgba + template struct comp_op_adaptor_clip_to_dst_rgba + { + typedef Order order_type; + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned ca, + unsigned cover) + { + cr = (cr * ca + base_mask) >> base_shift; + cg = (cg * ca + base_mask) >> base_shift; + cb = (cb * ca + base_mask) >> base_shift; + unsigned da = p[Order::A]; + comp_op_table_rgba::g_comp_op_func[op] + (p, (cr * da + base_mask) >> base_shift, + (cg * da + base_mask) >> base_shift, + (cb * da + base_mask) >> base_shift, + (ca * da + base_mask) >> base_shift, + cover); + } + }; + + //================================================comp_op_adaptor_rgba_pre + template struct comp_op_adaptor_rgba_pre + { + typedef Order order_type; + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned ca, + unsigned cover) + { + comp_op_table_rgba::g_comp_op_func[op](p, cr, cg, cb, ca, cover); + } + }; + + //=====================================comp_op_adaptor_clip_to_dst_rgba_pre + template struct comp_op_adaptor_clip_to_dst_rgba_pre + { + typedef Order order_type; + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned ca, + unsigned cover) + { + unsigned da = p[Order::A]; + comp_op_table_rgba::g_comp_op_func[op] + (p, (cr * da + base_mask) >> base_shift, + (cg * da + base_mask) >> base_shift, + (cb * da + base_mask) >> base_shift, + (ca * da + base_mask) >> base_shift, + cover); + } + }; + + //=======================================================comp_adaptor_rgba + template struct comp_adaptor_rgba + { + typedef typename BlenderPre::order_type order_type; + typedef typename BlenderPre::color_type color_type; + typedef typename color_type::value_type value_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned ca, + unsigned cover) + { + BlenderPre::blend_pix(p, + (cr * ca + base_mask) >> base_shift, + (cg * ca + base_mask) >> base_shift, + (cb * ca + base_mask) >> base_shift, + ca, cover); + } + }; + + //==========================================comp_adaptor_clip_to_dst_rgba + template struct comp_adaptor_clip_to_dst_rgba + { + typedef typename BlenderPre::order_type order_type; + typedef typename BlenderPre::color_type color_type; + typedef typename color_type::value_type value_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned ca, + unsigned cover) + { + cr = (cr * ca + base_mask) >> base_shift; + cg = (cg * ca + base_mask) >> base_shift; + cb = (cb * ca + base_mask) >> base_shift; + unsigned da = p[order_type::A]; + BlenderPre::blend_pix(p, + (cr * da + base_mask) >> base_shift, + (cg * da + base_mask) >> base_shift, + (cb * da + base_mask) >> base_shift, + (ca * da + base_mask) >> base_shift, + cover); + } + }; + + //======================================comp_adaptor_clip_to_dst_rgba_pre + template struct comp_adaptor_clip_to_dst_rgba_pre + { + typedef typename BlenderPre::order_type order_type; + typedef typename BlenderPre::color_type color_type; + typedef typename color_type::value_type value_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned ca, + unsigned cover) + { + unsigned da = p[order_type::A]; + BlenderPre::blend_pix(p, + (cr * da + base_mask) >> base_shift, + (cg * da + base_mask) >> base_shift, + (cb * da + base_mask) >> base_shift, + (ca * da + base_mask) >> base_shift, + cover); + } + }; + + + + + + + //===============================================copy_or_blend_rgba_wrapper + template struct copy_or_blend_rgba_wrapper + { + typedef typename Blender::color_type color_type; + typedef typename Blender::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 + }; + + //-------------------------------------------------------------------- + static AGG_INLINE void copy_or_blend_pix(value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha) + { + if(alpha) + { + if(alpha == base_mask) + { + p[order_type::R] = cr; + p[order_type::G] = cg; + p[order_type::B] = cb; + p[order_type::A] = base_mask; + } + else + { + Blender::blend_pix(p, cr, cg, cb, alpha); + } + } + } + + //-------------------------------------------------------------------- + static AGG_INLINE void copy_or_blend_pix(value_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + if(cover == 255) + { + copy_or_blend_pix(p, cr, cg, cb, alpha); + } + else + { + if(alpha) + { + alpha = (alpha * (cover + 1)) >> 8; + if(alpha == base_mask) + { + p[order_type::R] = cr; + p[order_type::G] = cg; + p[order_type::B] = cb; + p[order_type::A] = base_mask; + } + else + { + Blender::blend_pix(p, cr, cg, cb, alpha, cover); + } + } + } + } + }; + + + + + + + //=================================================pixfmt_alpha_blend_rgba + template + class pixfmt_alpha_blend_rgba + { + public: + typedef RenBuf rbuf_type; + typedef typename rbuf_type::row_data row_data; + typedef PixelT pixel_type; + typedef Blender blender_type; + 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; + typedef copy_or_blend_rgba_wrapper cob_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(pixel_type) + }; + + //-------------------------------------------------------------------- + pixfmt_alpha_blend_rgba() : m_rbuf(0) {} + pixfmt_alpha_blend_rgba(rbuf_type& rb) : m_rbuf(&rb) {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + template + 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(); } + + //-------------------------------------------------------------------- + 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; + ((value_type*)p)[order_type::A] = c.a; + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + const value_type* p = (const value_type*)m_rbuf->row_ptr(y); + if(p) + { + p += x << 2; + return color_type(p[order_type::R], + p[order_type::G], + p[order_type::B], + p[order_type::A]); + } + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + 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 << 2); + p[order_type::R] = c.r; + p[order_type::G] = c.g; + p[order_type::B] = c.b; + p[order_type::A] = c.a; + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + cob_type::copy_or_blend_pix( + (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2), + c.r, c.g, c.b, c.a, + 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 << 2); + pixel_type v; + ((value_type*)&v)[order_type::R] = c.r; + ((value_type*)&v)[order_type::G] = c.g; + ((value_type*)&v)[order_type::B] = c.b; + ((value_type*)&v)[order_type::A] = c.a; + do + { + *(pixel_type*)p = v; + p += 4; + } + while(--len); + } + + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v; + ((value_type*)&v)[order_type::R] = c.r; + ((value_type*)&v)[order_type::G] = c.g; + ((value_type*)&v)[order_type::B] = c.b; + ((value_type*)&v)[order_type::A] = c.a; + do + { + value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); + *(pixel_type*)p = 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 << 2); + calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; + if(alpha == base_mask) + { + pixel_type v; + ((value_type*)&v)[order_type::R] = c.r; + ((value_type*)&v)[order_type::G] = c.g; + ((value_type*)&v)[order_type::B] = c.b; + ((value_type*)&v)[order_type::A] = c.a; + do + { + *(pixel_type*)p = v; + p += 4; + } + while(--len); + } + else + { + if(cover == 255) + { + do + { + blender_type::blend_pix(p, c.r, c.g, c.b, alpha); + p += 4; + } + while(--len); + } + else + { + do + { + blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover); + p += 4; + } + 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) + { + pixel_type v; + ((value_type*)&v)[order_type::R] = c.r; + ((value_type*)&v)[order_type::G] = c.g; + ((value_type*)&v)[order_type::B] = c.b; + ((value_type*)&v)[order_type::A] = c.a; + do + { + p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); + *(pixel_type*)p = v; + } + while(--len); + } + else + { + if(cover == 255) + { + do + { + p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); + blender_type::blend_pix(p, c.r, c.g, c.b, alpha); + } + while(--len); + } + else + { + do + { + p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); + blender_type::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 << 2); + 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; + p[order_type::A] = base_mask; + } + else + { + blender_type::blend_pix(p, c.r, c.g, c.b, alpha, *covers); + } + p += 4; + ++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 << 2); + 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; + p[order_type::A] = base_mask; + } + else + { + blender_type::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 << 2); + do + { + p[order_type::R] = colors->r; + p[order_type::G] = colors->g; + p[order_type::B] = colors->b; + p[order_type::A] = colors->a; + ++colors; + p += 4; + } + 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 << 2); + p[order_type::R] = colors->r; + p[order_type::G] = colors->g; + p[order_type::B] = colors->b; + p[order_type::A] = colors->a; + ++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 << 2); + if(covers) + { + do + { + cob_type::copy_or_blend_pix(p, + colors->r, + colors->g, + colors->b, + colors->a, + *covers++); + p += 4; + ++colors; + } + while(--len); + } + else + { + if(cover == 255) + { + do + { + cob_type::copy_or_blend_pix(p, + colors->r, + colors->g, + colors->b, + colors->a); + p += 4; + ++colors; + } + while(--len); + } + else + { + do + { + cob_type::copy_or_blend_pix(p, + colors->r, + colors->g, + colors->b, + colors->a, + cover); + p += 4; + ++colors; + } + 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 << 2); + cob_type::copy_or_blend_pix(p, + colors->r, + colors->g, + colors->b, + colors->a, + *covers++); + ++colors; + } + while(--len); + } + else + { + if(cover == 255) + { + do + { + p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); + cob_type::copy_or_blend_pix(p, + colors->r, + colors->g, + colors->b, + colors->a); + ++colors; + } + while(--len); + } + else + { + do + { + p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); + cob_type::copy_or_blend_pix(p, + colors->r, + colors->g, + colors->b, + colors->a, + cover); + ++colors; + } + while(--len); + } + } + } + + //-------------------------------------------------------------------- + template 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 << 2); + do + { + f(p); + p += 4; + } + while(--len); + } + } + } + + //-------------------------------------------------------------------- + void premultiply() + { + for_each_pixel(multiplier_rgba::premultiply); + } + + //-------------------------------------------------------------------- + void demultiply() + { + for_each_pixel(multiplier_rgba::demultiply); + } + + //-------------------------------------------------------------------- + template void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_rgba(g)); + } + + //-------------------------------------------------------------------- + template void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_rgba(g)); + } + + //-------------------------------------------------------------------- + template 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 + 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 = (value_type*)from.row_ptr(ysrc); + if(psrc) + { + psrc += xsrc << 2; + value_type* pdst = + (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2); + int incp = 4; + if(xdst > xsrc) + { + psrc += (len-1) << 2; + pdst += (len-1) << 2; + incp = -4; + } + + if(cover == 255) + { + do + { + cob_type::copy_or_blend_pix(pdst, + psrc[src_order::R], + psrc[src_order::G], + psrc[src_order::B], + psrc[src_order::A]); + psrc += incp; + pdst += incp; + } + while(--len); + } + else + { + do + { + cob_type::copy_or_blend_pix(pdst, + psrc[src_order::R], + psrc[src_order::G], + psrc[src_order::B], + psrc[src_order::A], + cover); + psrc += incp; + pdst += incp; + } + while(--len); + } + } + } + + private: + rbuf_type* m_rbuf; + }; + + + + + //================================================pixfmt_custom_blend_rgba + template class pixfmt_custom_blend_rgba + { + 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 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) * 4 + }; + + + //-------------------------------------------------------------------- + pixfmt_custom_blend_rgba() : m_rbuf(0), m_comp_op(3) {} + pixfmt_custom_blend_rgba(rbuf_type& rb, unsigned comp_op=3) : + m_rbuf(&rb), + m_comp_op(comp_op) + {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + template + 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(); } + + //-------------------------------------------------------------------- + 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; + } + + //-------------------------------------------------------------------- + void comp_op(unsigned op) { m_comp_op = op; } + unsigned comp_op() const { return m_comp_op; } + + //-------------------------------------------------------------------- + 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; + ((value_type*)p)[order_type::A] = c.a; + } + + //-------------------------------------------------------------------- + color_type pixel(int x, int y) const + { + const value_type* p = (value_type*)m_rbuf->row_ptr(y) + (x << 2); + return color_type(p[order_type::R], + p[order_type::G], + p[order_type::B], + p[order_type::A]); + } + + //-------------------------------------------------------------------- + void copy_pixel(int x, int y, const color_type& c) + { + blender_type::blend_pix( + m_comp_op, + (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2), + c.r, c.g, c.b, c.a, 255); + } + + //-------------------------------------------------------------------- + void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + blender_type::blend_pix( + m_comp_op, + (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2), + c.r, c.g, c.b, c.a, + cover); + } + + //-------------------------------------------------------------------- + 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 << 2);; + do + { + blender_type::blend_pix(m_comp_op, p, c.r, c.g, c.b, c.a, 255); + p += 4; + } + while(--len); + } + + //-------------------------------------------------------------------- + void copy_vline(int x, int y, unsigned len, const color_type& c) + { + do + { + blender_type::blend_pix( + m_comp_op, + (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), + c.r, c.g, c.b, c.a, 255); + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, unsigned len, + const color_type& c, int8u cover) + { + + value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); + do + { + blender_type::blend_pix(m_comp_op, p, c.r, c.g, c.b, c.a, cover); + p += 4; + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, unsigned len, + const color_type& c, int8u cover) + { + + do + { + blender_type::blend_pix( + m_comp_op, + (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), + c.r, c.g, c.b, c.a, + cover); + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, unsigned len, + const color_type& c, const int8u* covers) + { + value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); + do + { + blender_type::blend_pix(m_comp_op, + p, c.r, c.g, c.b, c.a, + *covers++); + p += 4; + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, unsigned len, + const color_type& c, const int8u* covers) + { + do + { + blender_type::blend_pix( + m_comp_op, + (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), + c.r, c.g, c.b, c.a, + *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 << 2); + do + { + p[order_type::R] = colors->r; + p[order_type::G] = colors->g; + p[order_type::B] = colors->b; + p[order_type::A] = colors->a; + ++colors; + p += 4; + } + 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 << 2); + p[order_type::R] = colors->r; + p[order_type::G] = colors->g; + p[order_type::B] = colors->b; + p[order_type::A] = colors->a; + ++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 << 2); + do + { + blender_type::blend_pix(m_comp_op, + p, + colors->r, + colors->g, + colors->b, + colors->a, + covers ? *covers++ : cover); + 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 + { + blender_type::blend_pix( + m_comp_op, + (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), + colors->r, + colors->g, + colors->b, + colors->a, + covers ? *covers++ : cover); + ++colors; + } + while(--len); + + } + + //-------------------------------------------------------------------- + template 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 << 2); + do + { + f(p); + p += 4; + } + while(--len); + } + } + } + + //-------------------------------------------------------------------- + void premultiply() + { + for_each_pixel(multiplier_rgba::premultiply); + } + + //-------------------------------------------------------------------- + void demultiply() + { + for_each_pixel(multiplier_rgba::demultiply); + } + + //-------------------------------------------------------------------- + template void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_rgba(g)); + } + + //-------------------------------------------------------------------- + template void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_rgba(g)); + } + + //-------------------------------------------------------------------- + template 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 + 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 << 2; + value_type* pdst = + (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2); + + int incp = 4; + if(xdst > xsrc) + { + psrc += (len-1) << 2; + pdst += (len-1) << 2; + incp = -4; + } + + do + { + blender_type::blend_pix(m_comp_op, + pdst, + psrc[src_order::R], + psrc[src_order::G], + psrc[src_order::B], + psrc[src_order::A], + cover); + psrc += incp; + pdst += incp; + } + while(--len); + } + } + + private: + rbuf_type* m_rbuf; + unsigned m_comp_op; + }; + + + + + //----------------------------------------------------------------------- + typedef blender_rgba blender_rgba32; //----blender_rgba32 + typedef blender_rgba blender_argb32; //----blender_argb32 + typedef blender_rgba blender_abgr32; //----blender_abgr32 + typedef blender_rgba blender_bgra32; //----blender_bgra32 + + typedef blender_rgba_pre blender_rgba32_pre; //----blender_rgba32_pre + typedef blender_rgba_pre blender_argb32_pre; //----blender_argb32_pre + typedef blender_rgba_pre blender_abgr32_pre; //----blender_abgr32_pre + typedef blender_rgba_pre blender_bgra32_pre; //----blender_bgra32_pre + + typedef blender_rgba_plain blender_rgba32_plain; //----blender_rgba32_plain + typedef blender_rgba_plain blender_argb32_plain; //----blender_argb32_plain + typedef blender_rgba_plain blender_abgr32_plain; //----blender_abgr32_plain + typedef blender_rgba_plain blender_bgra32_plain; //----blender_bgra32_plain + + typedef blender_rgba blender_rgba64; //----blender_rgba64 + typedef blender_rgba blender_argb64; //----blender_argb64 + typedef blender_rgba blender_abgr64; //----blender_abgr64 + typedef blender_rgba blender_bgra64; //----blender_bgra64 + + typedef blender_rgba_pre blender_rgba64_pre; //----blender_rgba64_pre + typedef blender_rgba_pre blender_argb64_pre; //----blender_argb64_pre + typedef blender_rgba_pre blender_abgr64_pre; //----blender_abgr64_pre + typedef blender_rgba_pre blender_bgra64_pre; //----blender_bgra64_pre + + + //----------------------------------------------------------------------- + typedef int32u pixel32_type; + typedef pixfmt_alpha_blend_rgba pixfmt_rgba32; //----pixfmt_rgba32 + typedef pixfmt_alpha_blend_rgba pixfmt_argb32; //----pixfmt_argb32 + typedef pixfmt_alpha_blend_rgba pixfmt_abgr32; //----pixfmt_abgr32 + typedef pixfmt_alpha_blend_rgba pixfmt_bgra32; //----pixfmt_bgra32 + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba32_pre; //----pixfmt_rgba32_pre + typedef pixfmt_alpha_blend_rgba pixfmt_argb32_pre; //----pixfmt_argb32_pre + typedef pixfmt_alpha_blend_rgba pixfmt_abgr32_pre; //----pixfmt_abgr32_pre + typedef pixfmt_alpha_blend_rgba pixfmt_bgra32_pre; //----pixfmt_bgra32_pre + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba32_plain; //----pixfmt_rgba32_plain + typedef pixfmt_alpha_blend_rgba pixfmt_argb32_plain; //----pixfmt_argb32_plain + typedef pixfmt_alpha_blend_rgba pixfmt_abgr32_plain; //----pixfmt_abgr32_plain + typedef pixfmt_alpha_blend_rgba pixfmt_bgra32_plain; //----pixfmt_bgra32_plain + + struct pixel64_type { int16u c[4]; }; + typedef pixfmt_alpha_blend_rgba pixfmt_rgba64; //----pixfmt_rgba64 + typedef pixfmt_alpha_blend_rgba pixfmt_argb64; //----pixfmt_argb64 + typedef pixfmt_alpha_blend_rgba pixfmt_abgr64; //----pixfmt_abgr64 + typedef pixfmt_alpha_blend_rgba pixfmt_bgra64; //----pixfmt_bgra64 + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba64_pre; //----pixfmt_rgba64_pre + typedef pixfmt_alpha_blend_rgba pixfmt_argb64_pre; //----pixfmt_argb64_pre + typedef pixfmt_alpha_blend_rgba pixfmt_abgr64_pre; //----pixfmt_abgr64_pre + typedef pixfmt_alpha_blend_rgba pixfmt_bgra64_pre; //----pixfmt_bgra64_pre +} + +#endif + diff --git a/headers/libs/agg/agg_pixfmt_rgba32.h b/headers/libs/agg/agg_pixfmt_rgba32.h deleted file mode 100644 index a1a8cc2bc9..0000000000 --- a/headers/libs/agg/agg_pixfmt_rgba32.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_RGBA32_INCLUDED -#define AGG_PIXFMT_RGBA32_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_rendering_buffer.h" - -namespace agg -{ - - //====================================================pixel_formats_rgba32 - template 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 - 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 pixfmt_rgba32; //----pixfmt_rgba32 - typedef pixel_formats_rgba32 pixfmt_argb32; //----pixfmt_argb32 - typedef pixel_formats_rgba32 pixfmt_abgr32; //----pixfmt_abgr32 - typedef pixel_formats_rgba32 pixfmt_bgra32; //----pixfmt_bgra32 -} - -#endif - diff --git a/headers/libs/agg/agg_pixfmt_rgba32_plain.h b/headers/libs/agg/agg_pixfmt_rgba32_plain.h deleted file mode 100644 index 286e4ef247..0000000000 --- a/headers/libs/agg/agg_pixfmt_rgba32_plain.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_RGBA32_PLAIN_INCLUDED -#define AGG_PIXFMT_RGBA32_PLAIN_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_rendering_buffer.h" - -namespace agg -{ - - - //===============================================pixel_formats_rgba32_plain - template 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 pixfmt_rgba32_plain; //----pixfmt_rgba32_plain - typedef pixel_formats_rgba32_plain pixfmt_argb32_plain; //----pixfmt_argb32_plain - typedef pixel_formats_rgba32_plain pixfmt_abgr32_plain; //----pixfmt_abgr32_plain - typedef pixel_formats_rgba32_plain pixfmt_bgra32_plain; //----pixfmt_bgra32_plain -} - - -#endif diff --git a/headers/libs/agg/agg_pixfmt_rgba32_pre.h b/headers/libs/agg/agg_pixfmt_rgba32_pre.h deleted file mode 100644 index fb50ba8a6e..0000000000 --- a/headers/libs/agg/agg_pixfmt_rgba32_pre.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PIXFMT_RGBA32_PRE_INCLUDED -#define AGG_PIXFMT_RGBA32_PRE_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_rendering_buffer.h" - -namespace agg -{ - - - //=================================================pixel_formats_rgba32_pre - template 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 - 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 pixfmt_rgba32_pre; //----pixfmt_rgba32_pre - typedef pixel_formats_rgba32_pre pixfmt_argb32_pre; //----pixfmt_argb32_pre - typedef pixel_formats_rgba32_pre pixfmt_abgr32_pre; //----pixfmt_abgr32_pre - typedef pixel_formats_rgba32_pre pixfmt_bgra32_pre; //----pixfmt_bgra32_pre -} - - -#endif diff --git a/headers/libs/agg/agg_pixfmt_transposer.h b/headers/libs/agg/agg_pixfmt_transposer.h new file mode 100644 index 0000000000..723da7bb8a --- /dev/null +++ b/headers/libs/agg/agg_pixfmt_transposer.h @@ -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: mcseem@antigrain.com +// mcseemagg@yahoo.com +// 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_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 + + diff --git a/headers/libs/agg/agg_rasterizer_cells_aa.h b/headers/libs/agg/agg_rasterizer_cells_aa.h new file mode 100755 index 0000000000..59ffd77739 --- /dev/null +++ b/headers/libs/agg/agg_rasterizer_cells_aa.h @@ -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: mcseem@antigrain.com +// mcseemagg@yahoo.com +// 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 +#include +#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 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 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 m_sorted_cells; + pod_vector 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 + rasterizer_cells_aa::~rasterizer_cells_aa() + { + if(m_num_blocks) + { + cell_type** ptr = m_cells + m_num_blocks - 1; + while(m_num_blocks--) + { + pod_allocator::deallocate(*ptr, cell_block_size); + ptr--; + } + pod_allocator::deallocate(m_cells, m_max_blocks); + } + } + + //------------------------------------------------------------------------ + template + rasterizer_cells_aa::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 + void rasterizer_cells_aa::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 + AGG_INLINE void rasterizer_cells_aa::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 + AGG_INLINE void rasterizer_cells_aa::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 + AGG_INLINE void rasterizer_cells_aa::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 + AGG_INLINE void rasterizer_cells_aa::style(const cell_type& style_cell) + { + m_style_cell.style(style_cell); + } + + //------------------------------------------------------------------------ + template + void rasterizer_cells_aa::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 + void rasterizer_cells_aa::allocate_block() + { + if(m_curr_block >= m_num_blocks) + { + if(m_num_blocks >= m_max_blocks) + { + cell_type** new_cells = + pod_allocator::allocate(m_max_blocks + + cell_block_pool); + + if(m_cells) + { + memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*)); + pod_allocator::deallocate(m_cells, m_max_blocks); + } + m_cells = new_cells; + m_max_blocks += cell_block_pool; + } + + m_cells[m_num_blocks++] = + pod_allocator::allocate(cell_block_size); + + } + m_curr_cell_ptr = m_cells[m_curr_block++]; + } + + + + //------------------------------------------------------------------------ + template static AGG_INLINE void swap_cells(T* a, T* b) + { + T temp = *a; + *a = *b; + *b = temp; + } + + + //------------------------------------------------------------------------ + enum + { + qsort_threshold = 9 + }; + + + //------------------------------------------------------------------------ + template + 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 + void rasterizer_cells_aa::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 diff --git a/headers/libs/agg/agg_rasterizer_compound_aa.h b/headers/libs/agg/agg_rasterizer_compound_aa.h new file mode 100755 index 0000000000..8547747c88 --- /dev/null +++ b/headers/libs/agg/agg_rasterizer_compound_aa.h @@ -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: mcseem@antigrain.com +// mcseemagg@yahoo.com +// 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 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 + 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 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&); + const rasterizer_compound_aa& + operator = (const rasterizer_compound_aa&); + + private: + rasterizer_cells_aa m_outline; + clip_type m_clipper; + filling_rule_e m_filling_rule; + pod_vector m_styles; // Active Styles + pod_vector m_ast; // Active Style Table (unique values) + pod_vector m_asm; // Active Style Mask + pod_vector m_cells; + pod_vector m_cover_buf; + pod_bvector 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 + void rasterizer_compound_aa::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 + void rasterizer_compound_aa::filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + + //------------------------------------------------------------------------ + template + void rasterizer_compound_aa::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 + void rasterizer_compound_aa::reset_clipping() + { + reset(); + m_clipper.reset_clipping(); + } + + //------------------------------------------------------------------------ + template + void rasterizer_compound_aa::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 + void rasterizer_compound_aa::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 + void rasterizer_compound_aa::line_to(int x, int y) + { + m_clipper.line_to(m_outline, + conv_type::downscale(x), + conv_type::downscale(y)); + } + + //------------------------------------------------------------------------ + template + void rasterizer_compound_aa::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 + void rasterizer_compound_aa::line_to_d(double x, double y) + { + m_clipper.line_to(m_outline, + conv_type::upscale(x), + conv_type::upscale(y)); + } + + //------------------------------------------------------------------------ + template + void rasterizer_compound_aa::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 + void rasterizer_compound_aa::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 + void rasterizer_compound_aa::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 + AGG_INLINE void rasterizer_compound_aa::sort() + { + m_outline.sort_cells(); + } + + //------------------------------------------------------------------------ + template + AGG_INLINE bool rasterizer_compound_aa::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 + AGG_INLINE void rasterizer_compound_aa::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 + unsigned rasterizer_compound_aa::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 > 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 + AGG_INLINE + unsigned rasterizer_compound_aa::style(unsigned style_idx) const + { + return m_ast[style_idx + 1] + m_min_style - 1; + } + + //------------------------------------------------------------------------ + template + AGG_INLINE bool rasterizer_compound_aa::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 + bool rasterizer_compound_aa::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 + cover_type* rasterizer_compound_aa::allocate_cover_buffer(unsigned len) + { + m_cover_buf.allocate(len, 256); + return &m_cover_buf[0]; + } + + //------------------------------------------------------------------------ + template + void rasterizer_compound_aa::allocate_master_alpha() + { + while((int)m_master_alpha.size() <= m_max_style) + { + m_master_alpha.add(aa_mask); + } + } + + //------------------------------------------------------------------------ + template + void rasterizer_compound_aa::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 + diff --git a/headers/libs/agg/agg_rasterizer_outline.h b/headers/libs/agg/agg_rasterizer_outline.h index 2cd187e38c..cc2bd2f744 100644 --- a/headers/libs/agg/agg_rasterizer_outline.h +++ b/headers/libs/agg/agg_rasterizer_outline.h @@ -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 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 - 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 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; }; diff --git a/headers/libs/agg/agg_rasterizer_outline_aa.h b/headers/libs/agg/agg_rasterizer_outline_aa.h index 1ef5633d52..6ce3c31022 100644 --- a/headers/libs/agg/agg_rasterizer_outline_aa.h +++ b/headers/libs/agg/agg_rasterizer_outline_aa.h @@ -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 rasterizer_outline_aa + template class rasterizer_outline_aa { private: //------------------------------------------------------------------------ @@ -79,20 +86,24 @@ namespace agg typedef vertex_sequence 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 - 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 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&); - const rasterizer_outline_aa& operator = - (const rasterizer_outline_aa&); + rasterizer_outline_aa(const rasterizer_outline_aa&); + const rasterizer_outline_aa& operator = + (const rasterizer_outline_aa&); - 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 - void rasterizer_outline_aa::draw(draw_vars& dv, unsigned start, unsigned end) + template + void rasterizer_outline_aa::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 - void rasterizer_outline_aa::render(bool close_polygon) + template + void rasterizer_outline_aa::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)); } } diff --git a/headers/libs/agg/agg_rasterizer_scanline_aa.h b/headers/libs/agg/agg_rasterizer_scanline_aa.h index e7d3e53fda..2b69db6e44 100644 --- a/headers/libs/agg/agg_rasterizer_scanline_aa.h +++ b/headers/libs/agg/agg_rasterizer_scanline_aa.h @@ -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 -#include -#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 class rasterizer_scanline_aa + template 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 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 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 + 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 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 - 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&); - const rasterizer_scanline_aa& - operator = (const rasterizer_scanline_aa&); - - //-------------------------------------------------------------------- - 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&); + const rasterizer_scanline_aa& + operator = (const rasterizer_scanline_aa&); private: - outline_aa m_outline; - int m_gamma[aa_num]; + rasterizer_cells_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 - void rasterizer_scanline_aa::reset() + template + void rasterizer_scanline_aa::reset() { m_outline.reset(); m_status = status_initial; } //------------------------------------------------------------------------ - template - void rasterizer_scanline_aa::filling_rule(filling_rule_e filling_rule) + template + void rasterizer_scanline_aa::filling_rule(filling_rule_e filling_rule) { m_filling_rule = filling_rule; } //------------------------------------------------------------------------ - template - void rasterizer_scanline_aa::clip_box(double x1, double y1, double x2, double y2) + template + void rasterizer_scanline_aa::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 - void rasterizer_scanline_aa::reset_clipping() + template + void rasterizer_scanline_aa::reset_clipping() { reset(); - m_clipping = false; + m_clipper.reset_clipping(); } - - //------------------------------------------------------------------------ - template - void rasterizer_scanline_aa::move_to_no_clip(int x, int y) + template + void rasterizer_scanline_aa::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 - void rasterizer_scanline_aa::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 - void rasterizer_scanline_aa::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 - void rasterizer_scanline_aa::clip_segment(int x, int y) + template + void rasterizer_scanline_aa::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 + void rasterizer_scanline_aa::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 - void rasterizer_scanline_aa::add_vertex(double x, double y, unsigned cmd) + template + void rasterizer_scanline_aa::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 + void rasterizer_scanline_aa::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 + void rasterizer_scanline_aa::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 - void rasterizer_scanline_aa::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 - void rasterizer_scanline_aa::line_to(int x, int y) - { - if(m_clipping) - { - clip_segment(x, y); - } - else - { - line_to_no_clip(x, y); - } - } - - //------------------------------------------------------------------------ - template - void rasterizer_scanline_aa::close_polygon() - { - if(m_clipping) - { - clip_segment(m_start_x, m_start_y); - } - close_polygon_no_clip(); - } - - //------------------------------------------------------------------------ - template - void rasterizer_scanline_aa::move_to_d(double x, double y) - { - move_to(poly_coord(x), poly_coord(y)); - } - - //------------------------------------------------------------------------ - template - void rasterizer_scanline_aa::line_to_d(double x, double y) - { - line_to(poly_coord(x), poly_coord(y)); - } - - - //------------------------------------------------------------------------ - template - bool rasterizer_scanline_aa::hit_test(int tx, int ty) + template + void rasterizer_scanline_aa::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 + void rasterizer_scanline_aa::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 + void rasterizer_scanline_aa::sort() + { + m_outline.sort_cells(); + } + + //------------------------------------------------------------------------ + template + AGG_INLINE bool rasterizer_scanline_aa::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 + AGG_INLINE bool rasterizer_scanline_aa::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 + bool rasterizer_scanline_aa::hit_test(int tx, int ty) + { + if(!navigate_scanline(ty)) return false; + scanline_hit_test sl(tx); + sweep_scanline(sl); + return sl.hit(); + } + + } diff --git a/headers/libs/agg/agg_rasterizer_sl_clip.h b/headers/libs/agg/agg_rasterizer_sl_clip.h new file mode 100644 index 0000000000..e7ba065acc --- /dev/null +++ b/headers/libs/agg/agg_rasterizer_sl_clip.h @@ -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: mcseem@antigrain.com +// mcseemagg@yahoo.com +// 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::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::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 rasterizer_sl_clip + { + public: + typedef Conv conv_type; + typedef typename Conv::coord_type coord_type; + typedef rect_base 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 + 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 + 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 + 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 rasterizer_sl_clip_int; + typedef rasterizer_sl_clip rasterizer_sl_clip_int_sat; + typedef rasterizer_sl_clip rasterizer_sl_clip_int_3x; + typedef rasterizer_sl_clip rasterizer_sl_clip_dbl; + typedef rasterizer_sl_clip rasterizer_sl_clip_dbl_3x; + + +} + +#endif diff --git a/headers/libs/agg/agg_render_scanlines.h b/headers/libs/agg/agg_render_scanlines.h deleted file mode 100644 index de9f345730..0000000000 --- a/headers/libs/agg/agg_render_scanlines.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_RENDER_SCANLINES_INCLUDED -#define AGG_RENDER_SCANLINES_INCLUDED - -#include "agg_basics.h" - -namespace agg -{ - //========================================================render_scanlines - template - 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 - 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 - - - diff --git a/headers/libs/agg/agg_renderer_base.h b/headers/libs/agg/agg_renderer_base.h index f4d4bdf8ea..21f4487e32 100644 --- a/headers/libs/agg/agg_renderer_base.h +++ b/headers/libs/agg/agg_renderer_base.h @@ -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 + 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 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; }; diff --git a/headers/libs/agg/agg_renderer_markers.h b/headers/libs/agg/agg_renderer_markers.h index a0acb368bd..820f753079 100644 --- a/headers/libs/agg/agg_renderer_markers.h +++ b/headers/libs/agg/agg_renderer_markers.h @@ -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()); } diff --git a/headers/libs/agg/agg_renderer_mclip.h b/headers/libs/agg/agg_renderer_mclip.h index e4fe12c182..31da0edde6 100644 --- a/headers/libs/agg/agg_renderer_mclip.h +++ b/headers/libs/agg/agg_renderer_mclip.h @@ -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 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 + 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&); const renderer_mclip& operator = (const renderer_mclip&); - base_ren_type m_ren; - pod_deque m_clip; - unsigned m_curr_cb; - rect m_bounds; + base_ren_type m_ren; + pod_bvector m_clip; + unsigned m_curr_cb; + rect_i m_bounds; }; diff --git a/headers/libs/agg/agg_renderer_outline_aa.h b/headers/libs/agg/agg_renderer_outline_aa.h index 00e7140220..e3629db726 100644 --- a/headers/libs/agg/agg_renderer_outline_aa.h +++ b/headers/libs/agg/agg_renderer_outline_aa.h @@ -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 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 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 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 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 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::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 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 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 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 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 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 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 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; }; diff --git a/headers/libs/agg/agg_renderer_outline_image.h b/headers/libs/agg/agg_renderer_outline_image.h index 5056f51208..dd48450edb 100644 --- a/headers/libs/agg/agg_renderer_outline_image.h +++ b/headers/libs/agg/agg_renderer_outline_image.h @@ -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 +#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 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 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 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; }; diff --git a/headers/libs/agg/agg_renderer_primitives.h b/headers/libs/agg/agg_renderer_primitives.h index 502599bedd..fe4780d513 100644 --- a/headers/libs/agg/agg_renderer_primitives.h +++ b/headers/libs/agg/agg_renderer_primitives.h @@ -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); } //-------------------------------------------------------------------- diff --git a/headers/libs/agg/agg_renderer_raster_text.h b/headers/libs/agg/agg_renderer_raster_text.h index 366f6d1717..87b43f9600 100644 --- a/headers/libs/agg/agg_renderer_raster_text.h +++ b/headers/libs/agg/agg_renderer_raster_text.h @@ -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) { diff --git a/headers/libs/agg/agg_renderer_scanline.h b/headers/libs/agg/agg_renderer_scanline.h index e01eca29e6..615fffb42b 100644 --- a/headers/libs/agg/agg_renderer_scanline.h +++ b/headers/libs/agg/agg_renderer_scanline.h @@ -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 renderer_scanline_aa + //================================================render_scanline_aa_solid + template + 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 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 + 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 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 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 renderer_scanline_bin + + + + + + + //======================================================render_scanline_aa + template + 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 + 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 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 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 + 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 + 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 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 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 + 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 + 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 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 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 + 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 + 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 + 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 diff --git a/headers/libs/agg/agg_rendering_buffer.h b/headers/libs/agg/agg_rendering_buffer.h index 278d37ef86..54268bd788 100644 --- a/headers/libs/agg/agg_rendering_buffer.h +++ b/headers/libs/agg/agg_rendering_buffer.h @@ -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& mtx) + T const* const* rows() const { return &m_rows[0]; } + + //-------------------------------------------------------------------- + template + 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&); - const row_ptr_cache& operator = (const row_ptr_cache&); - - 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 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 }; diff --git a/headers/libs/agg/agg_rendering_buffer_dynarow.h b/headers/libs/agg/agg_rendering_buffer_dynarow.h index 733e01fdb9..7ae61c38c3 100644 --- a/headers/libs/agg/agg_rendering_buffer_dynarow.h +++ b/headers/libs/agg/agg_rendering_buffer_dynarow.h @@ -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 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::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::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&); - const rendering_buffer_dynarow& - operator = (const rendering_buffer_dynarow&); + 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 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 }; diff --git a/headers/libs/agg/agg_rounded_rect.h b/headers/libs/agg/agg_rounded_rect.h index 5c089c3e72..fe8d26f71b 100644 --- a/headers/libs/agg/agg_rounded_rect.h +++ b/headers/libs/agg/agg_rounded_rect.h @@ -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 iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: double m_x1; double m_y1; diff --git a/headers/libs/agg/agg_scanline_bin.h b/headers/libs/agg/agg_scanline_bin.h index ea7cc5219b..660292b613 100644 --- a/headers/libs/agg/agg_scanline_bin.h +++ b/headers/libs/agg/agg_scanline_bin.h @@ -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 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_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); - } } diff --git a/headers/libs/agg/agg_scanline_boolean_algebra.h b/headers/libs/agg/agg_scanline_boolean_algebra.h index 9edcbdf59e..bc2e9c9d51 100644 --- a/headers/libs/agg/agg_scanline_boolean_algebra.h +++ b/headers/libs/agg/agg_scanline_boolean_algebra.h @@ -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 - 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 + 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 - 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 add_span2; + sbool_add_span_empty 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 + void sbool_xor_shapes_abs_diff_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_add_span_aa add_functor1; + sbool_add_span_aa add_functor2; + sbool_xor_spans_aa 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; } } diff --git a/headers/libs/agg/agg_scanline_p.h b/headers/libs/agg/agg_scanline_p.h index 811efbcf9b..1d1cbe72f1 100755 --- a/headers/libs/agg/agg_scanline_p.h +++ b/headers/libs/agg/agg_scanline_p.h @@ -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 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&); - const scanline_p& operator = (const scanline_p&); + 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 m_covers; + cover_type* m_cover_ptr; + pod_array m_spans; + span* m_cur_span; }; - //------------------------------------------------------------------------ - template - void scanline_p::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_array_type; - //------------------------------------------------------------------------ - template - void scanline_p::reset_spans() - { - m_last_x = 0x7FFFFFF0; - m_cover_ptr = m_covers; - m_cur_span = m_spans; - m_cur_span->len = 0; - } - - - //------------------------------------------------------------------------ - template - void scanline_p::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 - void scanline_p::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 - void scanline_p::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 m_covers; + cover_type* m_cover_ptr; + span_array_type m_spans; + }; - //=============================================================scanline_p8 - typedef scanline_p scanline_p8; - - //============================================================scanline_p16 - typedef scanline_p scanline_p16; - - //============================================================scanline_p32 - typedef scanline_p scanline_p32; } diff --git a/headers/libs/agg/agg_scanline_storage_aa.h b/headers/libs/agg/agg_scanline_storage_aa.h index 243aa4eb3a..be452a88ff 100644 --- a/headers/libs/agg/agg_scanline_storage_aa.h +++ b/headers/libs/agg/agg_scanline_storage_aa.h @@ -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 @@ // mcseemagg@yahoo.com // 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 #include #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::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::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::allocate(dst.len); memcpy(dst.ptr, src.ptr, dst.len * sizeof(T)); m_extra_storage.add(dst); } } - pod_deque m_cells; - pod_deque m_extra_storage; + pod_bvector m_cells; + pod_bvector 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 m_covers; - pod_deque m_spans; - pod_deque m_scanlines; + scanline_cell_storage m_covers; + pod_bvector m_spans; + pod_bvector 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; diff --git a/headers/libs/agg/agg_scanline_storage_bin.h b/headers/libs/agg/agg_scanline_storage_bin.h index 679a3f35dc..d760016970 100644 --- a/headers/libs/agg/agg_scanline_storage_bin.h +++ b/headers/libs/agg/agg_scanline_storage_bin.h @@ -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 @@ // mcseemagg@yahoo.com // 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 #include #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 m_spans; - pod_deque m_scanlines; + pod_bvector m_spans; + pod_bvector 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; diff --git a/headers/libs/agg/agg_scanline_u.h b/headers/libs/agg/agg_scanline_u.h index 8dfb6e84f5..5a28ed17e1 100755 --- a/headers/libs/agg/agg_scanline_u.h +++ b/headers/libs/agg/agg_scanline_u.h @@ -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 @@ // mcseemagg@yahoo.com // 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 -#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 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(const scanline_u&); - const scanline_u& operator = (const scanline_u&); + 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 m_covers; + pod_array m_spans; + span* m_cur_span; }; - //------------------------------------------------------------------------ - template scanline_u::~scanline_u() - { - delete [] m_spans; - delete [] m_covers; - } - - //------------------------------------------------------------------------ - template scanline_u::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 void scanline_u::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 inline void scanline_u::reset_spans() - { - m_last_x = 0x7FFFFFF0; - m_cur_span = m_spans; - } - - - //------------------------------------------------------------------------ - template inline void scanline_u::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 void scanline_u::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 void scanline_u::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 scanline_u8; - - //============================================================scanline_u16 - typedef scanline_u scanline_u16; - - //============================================================scanline_u32 - typedef scanline_u scanline_u32; - - - //=============================================================scanline_am + //==========================================================scanline_u8_am // // The scanline container with alpha-masking // //------------------------------------------------------------------------ - template - class scanline_am : public scanline_u + template + class scanline_u8_am : public scanline_u8 { public: - typedef AlphaMask alpha_mask_type; - typedef CoverT cover_type; - typedef scanline_u 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::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 scanline_u8_am : public scanline_am + + + //===========================================================scanline32_u8 + class scanline32_u8 { public: - typedef AlphaMask alpha_mask_type; - typedef int8u cover_type; - typedef scanline_am 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_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 m_covers; + span_array_type m_spans; }; + + + + //========================================================scanline32_u8_am + // + // The scanline container with alpha-masking + // + //------------------------------------------------------------------------ + template + 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 diff --git a/headers/libs/agg/agg_shorten_path.h b/headers/libs/agg/agg_shorten_path.h index 31fa3a83d0..dd9929ff97 100644 --- a/headers/libs/agg/agg_shorten_path.h +++ b/headers/libs/agg/agg_shorten_path.h @@ -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. diff --git a/headers/libs/agg/agg_simul_eq.h b/headers/libs/agg/agg_simul_eq.h index 6c86d4a673..3d0dce4b44 100644 --- a/headers/libs/agg/agg_simul_eq.h +++ b/headers/libs/agg/agg_simul_eq.h @@ -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. diff --git a/headers/libs/agg/agg_span_allocator.h b/headers/libs/agg/agg_span_allocator.h index 863bb787da..201b69bb01 100644 --- a/headers/libs/agg/agg_span_allocator.h +++ b/headers/libs/agg/agg_span_allocator.h @@ -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&); - const span_allocator& operator = (const span_allocator&); - - unsigned m_max_span_len; - color_type* m_span; + pod_array m_span; }; } diff --git a/headers/libs/agg/agg_span_converter.h b/headers/libs/agg/agg_span_converter.h index fc16c44a6b..91d0f87c25 100644 --- a/headers/libs/agg/agg_span_converter.h +++ b/headers/libs/agg/agg_span_converter.h @@ -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 span_converter + template 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; }; } diff --git a/headers/libs/agg/agg_span_generator.h b/headers/libs/agg/agg_span_generator.h deleted file mode 100644 index aa8fa46ba5..0000000000 --- a/headers/libs/agg/agg_span_generator.h +++ /dev/null @@ -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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// 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 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 diff --git a/headers/libs/agg/agg_span_gouraud.h b/headers/libs/agg/agg_span_gouraud.h index 2f7c7ae9ce..2986c88fee 100644 --- a/headers/libs/agg/agg_span_gouraud.h +++ b/headers/libs/agg/agg_span_gouraud.h @@ -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,18 +18,15 @@ #include "agg_basics.h" #include "agg_math.h" -#include "agg_span_generator.h" namespace agg { //============================================================span_gouraud - template - class span_gouraud : public span_generator + template class span_gouraud { public: typedef ColorT color_type; - typedef Allocator alloc_type; struct coord_type { @@ -39,23 +36,21 @@ namespace agg }; //-------------------------------------------------------------------- - span_gouraud(alloc_type& alloc) : - span_generator(alloc), + span_gouraud() : m_vertex(0) { m_cmd[0] = path_cmd_stop; } //-------------------------------------------------------------------- - span_gouraud(alloc_type& alloc, - const color_type& c1, + span_gouraud(const color_type& c1, const color_type& c2, const color_type& c3, double x1, double y1, double x2, double y2, double x3, double y3, double d) : - span_generator(alloc) + m_vertex(0) { colors(c1, c2, c3); triangle(x1, y1, x2, y2, x3, y3, d); @@ -132,8 +127,6 @@ namespace agg return m_cmd[m_vertex++]; } - - protected: //-------------------------------------------------------------------- void arrange_vertices(coord_type* coord) const @@ -164,7 +157,6 @@ namespace agg } } - private: //-------------------------------------------------------------------- coord_type m_coord[3]; diff --git a/headers/libs/agg/agg_span_gouraud_gray.h b/headers/libs/agg/agg_span_gouraud_gray.h new file mode 100644 index 0000000000..d5fc39d102 --- /dev/null +++ b/headers/libs/agg/agg_span_gouraud_gray.h @@ -0,0 +1,241 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_SPAN_GOURAUD_GRAY_INCLUDED +#define AGG_SPAN_GOURAUD_GRAY_INCLUDED + +#include "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_dda_line.h" +#include "agg_span_gouraud.h" + +namespace agg +{ + + //=======================================================span_gouraud_gray + template class span_gouraud_gray : public span_gouraud + { + public: + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + typedef span_gouraud base_type; + typedef typename base_type::coord_type coord_type; + enum subpixel_scale_e + { + subpixel_shift = 4, + subpixel_scale = 1 << subpixel_shift + }; + + private: + //-------------------------------------------------------------------- + struct gray_calc + { + void init(const coord_type& c1, const coord_type& c2) + { + m_x1 = c1.x - 0.5; + m_y1 = c1.y - 0.5; + m_dx = c2.x - c1.x; + double dy = c2.y - c1.y; + m_1dy = (fabs(dy) < 1e-10) ? 1e10 : 1.0 / dy; + m_v1 = c1.color.v; + m_a1 = c1.color.a; + m_dv = c2.color.v - m_v1; + m_da = c2.color.a - m_a1; + } + + void calc(double y) + { + double k = (y - m_y1) * m_1dy; + if(k < 0.0) k = 0.0; + if(k > 1.0) k = 1.0; + m_v = m_v1 + iround(m_dv * k); + m_a = m_a1 + iround(m_da * k); + m_x = iround((m_x1 + m_dx * k) * subpixel_scale); + } + + double m_x1; + double m_y1; + double m_dx; + double m_1dy; + int m_v1; + int m_a1; + int m_dv; + int m_da; + int m_v; + int m_a; + int m_x; + }; + + + public: + //-------------------------------------------------------------------- + span_gouraud_gray() {} + span_gouraud_gray(const color_type& c1, + const color_type& c2, + const color_type& c3, + double x1, double y1, + double x2, double y2, + double x3, double y3, + double d = 0) : + base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d) + {} + + //-------------------------------------------------------------------- + void prepare() + { + coord_type coord[3]; + base_type::arrange_vertices(coord); + + m_y2 = int(coord[1].y); + + m_swap = cross_product(coord[0].x, coord[0].y, + coord[2].x, coord[2].y, + coord[1].x, coord[1].y) < 0.0; + + m_c1.init(coord[0], coord[2]); + m_c2.init(coord[0], coord[1]); + m_c3.init(coord[1], coord[2]); + } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + m_c1.calc(y); + const gray_calc* pc1 = &m_c1; + const gray_calc* pc2 = &m_c2; + + if(y < m_y2) + { + // Bottom part of the triangle (first subtriangle) + //------------------------- + m_c2.calc(y + m_c2.m_1dy); + } + else + { + // Upper part (second subtriangle) + //------------------------- + m_c3.calc(y - m_c3.m_1dy); + pc2 = &m_c3; + } + + if(m_swap) + { + // It means that the triangle is oriented clockwise, + // so that we need to swap the controlling structures + //------------------------- + const gray_calc* t = pc2; + pc2 = pc1; + pc1 = t; + } + + // Get the horizontal length with subpixel accuracy + // and protect it from division by zero + //------------------------- + int nlen = abs(pc2->m_x - pc1->m_x); + if(nlen <= 0) nlen = 1; + + dda_line_interpolator<14> v(pc1->m_v, pc2->m_v, nlen); + dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen); + + // Calculate the starting point of the gradient with subpixel + // accuracy and correct (roll back) the interpolators. + // This operation will also clip the beginning of the span + // if necessary. + //------------------------- + int start = pc1->m_x - (x << subpixel_shift); + v -= start; + a -= start; + nlen += start; + + int vv, va; + enum lim_e { lim = color_type::base_mask }; + + // Beginning part of the span. Since we rolled back the + // interpolators, the color values may have overflow. + // So that, we render the beginning part with checking + // for overflow. It lasts until "start" is positive; + // typically it's 1-2 pixels, but may be more in some cases. + //------------------------- + while(len && start > 0) + { + vv = v.y(); + va = a.y(); + if(vv < 0) vv = 0; if(vv > lim) vv = lim; + if(va < 0) va = 0; if(va > lim) va = lim; + span->v = (value_type)vv; + span->a = (value_type)va; + v += subpixel_scale; + a += subpixel_scale; + nlen -= subpixel_scale; + start -= subpixel_scale; + ++span; + --len; + } + + // Middle part, no checking for overflow. + // Actual spans can be longer than the calculated length + // because of anti-aliasing, thus, the interpolators can + // overflow. But while "nlen" is positive we are safe. + //------------------------- + while(len && nlen > 0) + { + span->v = (value_type)v.y(); + span->a = (value_type)a.y(); + v += subpixel_scale; + a += subpixel_scale; + nlen -= subpixel_scale; + ++span; + --len; + } + + // Ending part; checking for overflow. + // Typically it's 1-2 pixels, but may be more in some cases. + //------------------------- + while(len) + { + vv = v.y(); + va = a.y(); + if(vv < 0) vv = 0; if(vv > lim) vv = lim; + if(va < 0) va = 0; if(va > lim) va = lim; + span->v = (value_type)vv; + span->a = (value_type)va; + v += subpixel_scale; + a += subpixel_scale; + ++span; + --len; + } + } + + + private: + bool m_swap; + int m_y2; + gray_calc m_c1; + gray_calc m_c2; + gray_calc m_c3; + }; + + +} + +#endif diff --git a/headers/libs/agg/agg_span_gouraud_gray8.h b/headers/libs/agg/agg_span_gouraud_gray8.h deleted file mode 100644 index ab05826326..0000000000 --- a/headers/libs/agg/agg_span_gouraud_gray8.h +++ /dev/null @@ -1,176 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_SPAN_GOURAUD_GRAY8_INCLUDED -#define AGG_SPAN_GOURAUD_GRAY8_INCLUDED - -#include "agg_basics.h" -#include "agg_gray8.h" -#include "agg_dda_line.h" -#include "agg_span_gouraud.h" - -namespace agg -{ - - //======================================================span_gouraud_gray8 - template > - class span_gouraud_gray8 : public span_gouraud - { - public: - typedef Allocator alloc_type; - typedef gray8 color_type; - typedef span_gouraud base_type; - typedef typename base_type::coord_type coord_type; - - private: - //-------------------------------------------------------------------- - struct gray_calc - { - void init(const coord_type& c1, const coord_type& c2) - { - m_x1 = c1.x; - m_y1 = c1.y; - m_dx = c2.x - c1.x; - m_dy = 1.0 / (c2.y - c1.y); - m_v1 = c1.color.v; - m_a1 = c1.color.a; - m_dv = c2.color.v - m_v1; - m_da = c2.color.a - m_a1; - } - - void calc(int y) - { - double k = 0.0; - if(y > m_y1) k = (y - m_y1) * m_dy; - gray8 c; - m_v = m_v1 + int(m_dv * k); - m_a = m_a1 + int(m_da * k); - m_x = int(m_x1 + m_dx * k); - } - - double m_x1; - double m_y1; - double m_dx; - double m_dy; - int m_v1; - int m_a1; - int m_dv; - int m_da; - int m_v; - int m_a; - int m_x; - }; - - - public: - //-------------------------------------------------------------------- - span_gouraud_gray8(alloc_type& alloc) : base_type(alloc) {} - - //-------------------------------------------------------------------- - span_gouraud_gray8(alloc_type& alloc, - const color_type& c1, - const color_type& c2, - const color_type& c3, - double x1, double y1, - double x2, double y2, - double x3, double y3, - double d = 0) : - base_type(alloc, c1, c2, c3, x1, y1, x2, y2, x3, y3, d) - {} - - //-------------------------------------------------------------------- - void prepare(unsigned max_span_len) - { - base_type::prepare(max_span_len); - - coord_type coord[3]; - arrange_vertices(coord); - - m_y2 = int(coord[1].y); - - m_swap = calc_point_location(coord[0].x, coord[0].y, - coord[2].x, coord[2].y, - coord[1].x, coord[1].y) < 0.0; - - m_c1.init(coord[0], coord[2]); - m_c2.init(coord[0], coord[1]); - m_c3.init(coord[1], coord[2]); - } - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - m_c1.calc(y); - const gray_calc* pc1 = &m_c1; - const gray_calc* pc2 = &m_c2; - - if(y < m_y2) - { - m_c2.calc(y+1); - } - else - { - m_c3.calc(y); - pc2 = &m_c3; - } - - if(m_swap) - { - const gray_calc* t = pc2; - pc2 = pc1; - pc1 = t; - } - - int nx = pc1->m_x; - unsigned nlen = pc2->m_x - pc1->m_x + 1; - - if(nlen < len) nlen = len; - - dda_line_interpolator<16> v(pc1->m_v, pc2->m_v, nlen); - dda_line_interpolator<16> a(pc1->m_a, pc2->m_a, nlen); - - if(nx < x) - { - unsigned d = unsigned(x - nx); - v += d; - a += d; - } - - color_type* span = base_type::allocator().span(); - do - { - span->v = v.y(); - span->a = a.y(); - ++v; - ++a; - ++span; - } - while(--len); - return base_type::allocator().span(); - } - - - private: - bool m_swap; - int m_y2; - gray_calc m_c1; - gray_calc m_c2; - gray_calc m_c3; - }; - - -} - -#endif diff --git a/headers/libs/agg/agg_span_gouraud_rgba.h b/headers/libs/agg/agg_span_gouraud_rgba.h new file mode 100644 index 0000000000..89192d227b --- /dev/null +++ b/headers/libs/agg/agg_span_gouraud_rgba.h @@ -0,0 +1,277 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_SPAN_GOURAUD_RGBA_INCLUDED +#define AGG_SPAN_GOURAUD_RGBA_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_dda_line.h" +#include "agg_span_gouraud.h" + +namespace agg +{ + + //=======================================================span_gouraud_rgba + template class span_gouraud_rgba : public span_gouraud + { + public: + typedef ColorT color_type; + typedef typename ColorT::value_type value_type; + typedef span_gouraud base_type; + typedef typename base_type::coord_type coord_type; + enum subpixel_scale_e + { + subpixel_shift = 4, + subpixel_scale = 1 << subpixel_shift + }; + + private: + //-------------------------------------------------------------------- + struct rgba_calc + { + void init(const coord_type& c1, const coord_type& c2) + { + m_x1 = c1.x - 0.5; + m_y1 = c1.y - 0.5; + m_dx = c2.x - c1.x; + double dy = c2.y - c1.y; + m_1dy = (dy < 1e-5) ? 1e5 : 1.0 / dy; + m_r1 = c1.color.r; + m_g1 = c1.color.g; + m_b1 = c1.color.b; + m_a1 = c1.color.a; + m_dr = c2.color.r - m_r1; + m_dg = c2.color.g - m_g1; + m_db = c2.color.b - m_b1; + m_da = c2.color.a - m_a1; + } + + void calc(double y) + { + double k = (y - m_y1) * m_1dy; + if(k < 0.0) k = 0.0; + if(k > 1.0) k = 1.0; + m_r = m_r1 + iround(m_dr * k); + m_g = m_g1 + iround(m_dg * k); + m_b = m_b1 + iround(m_db * k); + m_a = m_a1 + iround(m_da * k); + m_x = iround((m_x1 + m_dx * k) * subpixel_scale); + } + + double m_x1; + double m_y1; + double m_dx; + double m_1dy; + int m_r1; + int m_g1; + int m_b1; + int m_a1; + int m_dr; + int m_dg; + int m_db; + int m_da; + int m_r; + int m_g; + int m_b; + int m_a; + int m_x; + }; + + public: + + //-------------------------------------------------------------------- + span_gouraud_rgba() {} + span_gouraud_rgba(const color_type& c1, + const color_type& c2, + const color_type& c3, + double x1, double y1, + double x2, double y2, + double x3, double y3, + double d = 0) : + base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d) + {} + + //-------------------------------------------------------------------- + void prepare() + { + coord_type coord[3]; + base_type::arrange_vertices(coord); + + m_y2 = int(coord[1].y); + + m_swap = cross_product(coord[0].x, coord[0].y, + coord[2].x, coord[2].y, + coord[1].x, coord[1].y) < 0.0; + + m_rgba1.init(coord[0], coord[2]); + m_rgba2.init(coord[0], coord[1]); + m_rgba3.init(coord[1], coord[2]); + } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + m_rgba1.calc(y);//(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y); + const rgba_calc* pc1 = &m_rgba1; + const rgba_calc* pc2 = &m_rgba2; + + if(y <= m_y2) + { + // Bottom part of the triangle (first subtriangle) + //------------------------- + m_rgba2.calc(y + m_rgba2.m_1dy); + } + else + { + // Upper part (second subtriangle) + m_rgba3.calc(y - m_rgba3.m_1dy); + //------------------------- + pc2 = &m_rgba3; + } + + if(m_swap) + { + // It means that the triangle is oriented clockwise, + // so that we need to swap the controlling structures + //------------------------- + const rgba_calc* t = pc2; + pc2 = pc1; + pc1 = t; + } + + // Get the horizontal length with subpixel accuracy + // and protect it from division by zero + //------------------------- + int nlen = abs(pc2->m_x - pc1->m_x); + if(nlen <= 0) nlen = 1; + + dda_line_interpolator<14> r(pc1->m_r, pc2->m_r, nlen); + dda_line_interpolator<14> g(pc1->m_g, pc2->m_g, nlen); + dda_line_interpolator<14> b(pc1->m_b, pc2->m_b, nlen); + dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen); + + // Calculate the starting point of the gradient with subpixel + // accuracy and correct (roll back) the interpolators. + // This operation will also clip the beginning of the span + // if necessary. + //------------------------- + int start = pc1->m_x - (x << subpixel_shift); + r -= start; + g -= start; + b -= start; + a -= start; + nlen += start; + + int vr, vg, vb, va; + enum lim_e { lim = color_type::base_mask }; + + // Beginning part of the span. Since we rolled back the + // interpolators, the color values may have overflow. + // So that, we render the beginning part with checking + // for overflow. It lasts until "start" is positive; + // typically it's 1-2 pixels, but may be more in some cases. + //------------------------- + while(len && start > 0) + { + vr = r.y(); + vg = g.y(); + vb = b.y(); + va = a.y(); + if(vr < 0) vr = 0; if(vr > lim) vr = lim; + if(vg < 0) vg = 0; if(vg > lim) vg = lim; + if(vb < 0) vb = 0; if(vb > lim) vb = lim; + if(va < 0) va = 0; if(va > lim) va = lim; + span->r = (value_type)vr; + span->g = (value_type)vg; + span->b = (value_type)vb; + span->a = (value_type)va; + r += subpixel_scale; + g += subpixel_scale; + b += subpixel_scale; + a += subpixel_scale; + nlen -= subpixel_scale; + start -= subpixel_scale; + ++span; + --len; + } + + // Middle part, no checking for overflow. + // Actual spans can be longer than the calculated length + // because of anti-aliasing, thus, the interpolators can + // overflow. But while "nlen" is positive we are safe. + //------------------------- + while(len && nlen > 0) + { + span->r = (value_type)r.y(); + span->g = (value_type)g.y(); + span->b = (value_type)b.y(); + span->a = (value_type)a.y(); + r += subpixel_scale; + g += subpixel_scale; + b += subpixel_scale; + a += subpixel_scale; + nlen -= subpixel_scale; + ++span; + --len; + } + + // Ending part; checking for overflow. + // Typically it's 1-2 pixels, but may be more in some cases. + //------------------------- + while(len) + { + vr = r.y(); + vg = g.y(); + vb = b.y(); + va = a.y(); + if(vr < 0) vr = 0; if(vr > lim) vr = lim; + if(vg < 0) vg = 0; if(vg > lim) vg = lim; + if(vb < 0) vb = 0; if(vb > lim) vb = lim; + if(va < 0) va = 0; if(va > lim) va = lim; + span->r = (value_type)vr; + span->g = (value_type)vg; + span->b = (value_type)vb; + span->a = (value_type)va; + r += subpixel_scale; + g += subpixel_scale; + b += subpixel_scale; + a += subpixel_scale; + ++span; + --len; + } + } + + private: + bool m_swap; + int m_y2; + rgba_calc m_rgba1; + rgba_calc m_rgba2; + rgba_calc m_rgba3; + }; + + + +} + +#endif diff --git a/headers/libs/agg/agg_span_gouraud_rgba8.h b/headers/libs/agg/agg_span_gouraud_rgba8.h deleted file mode 100644 index ed23892d6c..0000000000 --- a/headers/libs/agg/agg_span_gouraud_rgba8.h +++ /dev/null @@ -1,197 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_SPAN_GOURAUD_RGBA8_INCLUDED -#define AGG_SPAN_GOURAUD_RGBA8_INCLUDED - -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_dda_line.h" -#include "agg_span_gouraud.h" - -namespace agg -{ - - //======================================================span_gouraud_rgba8 - template > - class span_gouraud_rgba8 : public span_gouraud - { - public: - typedef Allocator alloc_type; - typedef rgba8 color_type; - typedef span_gouraud base_type; - typedef typename base_type::coord_type coord_type; - - private: - //-------------------------------------------------------------------- - struct rgba_calc - { - void init(const coord_type& c1, const coord_type& c2) - { - m_x1 = c1.x; - m_y1 = c1.y; - m_dx = c2.x - c1.x; - m_dy = 1.0 / (c2.y - c1.y); - m_r1 = c1.color.r; - m_g1 = c1.color.g; - m_b1 = c1.color.b; - m_a1 = c1.color.a; - m_dr = c2.color.r - m_r1; - m_dg = c2.color.g - m_g1; - m_db = c2.color.b - m_b1; - m_da = c2.color.a - m_a1; - } - - void calc(int y) - { - double k = 0.0; - if(y > m_y1) k = (y - m_y1) * m_dy; - rgba8 rgba; - m_r = m_r1 + int(m_dr * k); - m_g = m_g1 + int(m_dg * k); - m_b = m_b1 + int(m_db * k); - m_a = m_a1 + int(m_da * k); - m_x = int(m_x1 + m_dx * k); - } - - double m_x1; - double m_y1; - double m_dx; - double m_dy; - int m_r1; - int m_g1; - int m_b1; - int m_a1; - int m_dr; - int m_dg; - int m_db; - int m_da; - int m_r; - int m_g; - int m_b; - int m_a; - int m_x; - }; - - public: - - //-------------------------------------------------------------------- - span_gouraud_rgba8(alloc_type& alloc) : base_type(alloc) {} - - //-------------------------------------------------------------------- - span_gouraud_rgba8(alloc_type& alloc, - const color_type& c1, - const color_type& c2, - const color_type& c3, - double x1, double y1, - double x2, double y2, - double x3, double y3, - double d = 0) : - base_type(alloc, c1, c2, c3, x1, y1, x2, y2, x3, y3, d) - {} - - //-------------------------------------------------------------------- - void prepare(unsigned max_span_len) - { - base_type::prepare(max_span_len); - - coord_type coord[3]; - arrange_vertices(coord); - - m_y2 = int(coord[1].y); - - m_swap = calc_point_location(coord[0].x, coord[0].y, - coord[2].x, coord[2].y, - coord[1].x, coord[1].y) < 0.0; - - m_rgba1.init(coord[0], coord[2]); - m_rgba2.init(coord[0], coord[1]); - m_rgba3.init(coord[1], coord[2]); - } - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - m_rgba1.calc(y); - const rgba_calc* pc1 = &m_rgba1; - const rgba_calc* pc2 = &m_rgba2; - - if(y < m_y2) - { - m_rgba2.calc(y+1); - } - else - { - m_rgba3.calc(y); - pc2 = &m_rgba3; - } - - if(m_swap) - { - const rgba_calc* t = pc2; - pc2 = pc1; - pc1 = t; - } - - int nx = pc1->m_x; - unsigned nlen = pc2->m_x - pc1->m_x + 1; - - if(nlen < len) nlen = len; - - dda_line_interpolator<16> r(pc1->m_r, pc2->m_r, nlen); - dda_line_interpolator<16> g(pc1->m_g, pc2->m_g, nlen); - dda_line_interpolator<16> b(pc1->m_b, pc2->m_b, nlen); - dda_line_interpolator<16> a(pc1->m_a, pc2->m_a, nlen); - - if(nx < x) - { - unsigned d = unsigned(x - nx); - r += d; - g += d; - b += d; - a += d; - } - - color_type* span = base_type::allocator().span(); - do - { - span->r = (int8u)r.y(); - span->g = (int8u)g.y(); - span->b = (int8u)b.y(); - span->a = (int8u)a.y(); - ++r; - ++g; - ++b; - ++a; - ++span; - } - while(--len); - return base_type::allocator().span(); - } - - - private: - bool m_swap; - int m_y2; - rgba_calc m_rgba1; - rgba_calc m_rgba2; - rgba_calc m_rgba3; - }; - - - -} - -#endif diff --git a/headers/libs/agg/agg_span_gouraud_rgba8_gamma.h b/headers/libs/agg/agg_span_gouraud_rgba8_gamma.h deleted file mode 100644 index dc4e0d27b4..0000000000 --- a/headers/libs/agg/agg_span_gouraud_rgba8_gamma.h +++ /dev/null @@ -1,207 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_SPAN_GOURAUD_RGBA8_GAMMA_INCLUDED -#define AGG_SPAN_GOURAUD_RGBA8_GAMMA_INCLUDED - -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_dda_line.h" -#include "agg_span_gouraud.h" -#include "agg_gamma_lut.h" - -namespace agg -{ - - //======================================================span_gouraud_rgba8 - template, - class Gamma = gamma_lut > - class span_gouraud_rgba8_gamma : public span_gouraud - { - public: - typedef Allocator alloc_type; - typedef rgba8 color_type; - typedef span_gouraud base_type; - typedef typename base_type::coord_type coord_type; - typedef Gamma gamma_type; - - private: - //-------------------------------------------------------------------- - struct rgba_calc - { - void init(const coord_type& c1, const coord_type& c2, const gamma_type& gamma) - { - m_x1 = c1.x; - m_y1 = c1.y; - m_dx = c2.x - c1.x; - m_dy = 1.0 / (c2.y - c1.y); - m_r1 = gamma.dir(c1.color.r); - m_g1 = gamma.dir(c1.color.g); - m_b1 = gamma.dir(c1.color.b); - m_a1 = c1.color.a; - m_dr = gamma.dir(c2.color.r) - m_r1; - m_dg = gamma.dir(c2.color.g) - m_g1; - m_db = gamma.dir(c2.color.b) - m_b1; - m_da = c2.color.a - m_a1; - } - - void calc(int y) - { - double k = 0.0; - if(y > m_y1) k = (y - m_y1) * m_dy; - m_r = m_r1 + int(m_dr * k); - m_g = m_g1 + int(m_dg * k); - m_b = m_b1 + int(m_db * k); - m_a = m_a1 + int(m_da * k); - m_x = int(m_x1 + m_dx * k); - } - - double m_x1; - double m_y1; - double m_dx; - double m_dy; - int m_r1; - int m_g1; - int m_b1; - int m_a1; - int m_dr; - int m_dg; - int m_db; - int m_da; - int m_r; - int m_g; - int m_b; - int m_a; - int m_x; - }; - - public: - - //-------------------------------------------------------------------- - span_gouraud_rgba8_gamma(alloc_type& alloc, const gamma_type& g) : - base_type(alloc), m_gamma(&g) {} - - //-------------------------------------------------------------------- - span_gouraud_rgba8_gamma(alloc_type& alloc, - const gamma_type& g, - const color_type& c1, - const color_type& c2, - const color_type& c3, - double x1, double y1, - double x2, double y2, - double x3, double y3, - double d = 0) : - base_type(alloc, c1, c2, c3, x1, y1, x2, y2, x3, y3, d), - m_gamma(&g) - {} - - //-------------------------------------------------------------------- - void gamma(const gamma_type& g) { m_gamma = &g; } - const gamma_type& gamma() const { return *m_gamma; } - - //-------------------------------------------------------------------- - void prepare(unsigned max_span_len) - { - base_type::prepare(max_span_len); - - coord_type coord[3]; - arrange_vertices(coord); - - m_y2 = int(coord[1].y); - - m_swap = calc_point_location(coord[0].x, coord[0].y, - coord[2].x, coord[2].y, - coord[1].x, coord[1].y) < 0.0; - - m_rgba1.init(coord[0], coord[2], *m_gamma); - m_rgba2.init(coord[0], coord[1], *m_gamma); - m_rgba3.init(coord[1], coord[2], *m_gamma); - } - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - m_rgba1.calc(y); - const rgba_calc* pc1 = &m_rgba1; - const rgba_calc* pc2 = &m_rgba2; - - if(y < m_y2) - { - m_rgba2.calc(y+1); - } - else - { - m_rgba3.calc(y); - pc2 = &m_rgba3; - } - - if(m_swap) - { - const rgba_calc* t = pc2; - pc2 = pc1; - pc1 = t; - } - - int nx = pc1->m_x; - unsigned nlen = pc2->m_x - pc1->m_x + 1; - - if(nlen < len) nlen = len; - - dda_line_interpolator<8> r(pc1->m_r, pc2->m_r, nlen); - dda_line_interpolator<8> g(pc1->m_g, pc2->m_g, nlen); - dda_line_interpolator<8> b(pc1->m_b, pc2->m_b, nlen); - dda_line_interpolator<16> a(pc1->m_a, pc2->m_a, nlen); - - if(nx < x) - { - unsigned d = unsigned(x - nx); - r += d; - g += d; - b += d; - a += d; - } - - color_type* span = base_type::allocator().span(); - do - { - span->r = m_gamma->inv(r.y()); - span->g = m_gamma->inv(g.y()); - span->b = m_gamma->inv(b.y()); - span->a = a.y(); - ++r; - ++g; - ++b; - ++a; - ++span; - } - while(--len); - return base_type::allocator().span(); - } - - - private: - const gamma_type* m_gamma; - bool m_swap; - int m_y2; - rgba_calc m_rgba1; - rgba_calc m_rgba2; - rgba_calc m_rgba3; - }; - - - -} - -#endif diff --git a/headers/libs/agg/agg_span_gradient.h b/headers/libs/agg/agg_span_gradient.h index a60f81cf17..6047bf8747 100644 --- a/headers/libs/agg/agg_span_gradient.h +++ b/headers/libs/agg/agg_span_gradient.h @@ -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,80 +18,76 @@ #include #include +#include #include "agg_basics.h" -#include "agg_span_generator.h" #include "agg_math.h" +#include "agg_array.h" namespace agg { - enum + enum gradient_subpixel_scale_e { - gradient_subpixel_shift = 4, - gradient_subpixel_size = 1 << gradient_subpixel_shift, - gradient_subpixel_mask = gradient_subpixel_size - 1 + gradient_subpixel_shift = 4, //-----gradient_subpixel_shift + gradient_subpixel_scale = 1 << gradient_subpixel_shift, //-----gradient_subpixel_scale + gradient_subpixel_mask = gradient_subpixel_scale - 1 //-----gradient_subpixel_mask }; + //==========================================================span_gradient - template > - class span_gradient : public span_generator + class ColorF> + class span_gradient { public: typedef Interpolator interpolator_type; - typedef Allocator alloc_type; typedef ColorT color_type; - typedef span_generator base_type; - enum + enum downscale_shift_e { - base_shift = 8, - base_size = 1 << base_shift, - base_mask = base_size - 1, - downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift + downscale_shift = interpolator_type::subpixel_shift - + gradient_subpixel_shift }; + //-------------------------------------------------------------------- + span_gradient() {} //-------------------------------------------------------------------- - span_gradient(alloc_type& alloc) : base_type(alloc) {} - - //-------------------------------------------------------------------- - span_gradient(alloc_type& alloc, - interpolator_type& inter, + span_gradient(interpolator_type& inter, const GradientF& gradient_function, - ColorF color_function, + const ColorF& color_function, double d1, double d2) : - base_type(alloc), m_interpolator(&inter), m_gradient_function(&gradient_function), - m_color_function(color_function), - m_d1(int(d1 * gradient_subpixel_size)), - m_d2(int(d2 * gradient_subpixel_size)) + m_color_function(&color_function), + m_d1(iround(d1 * gradient_subpixel_scale)), + m_d2(iround(d2 * gradient_subpixel_scale)) {} //-------------------------------------------------------------------- interpolator_type& interpolator() { return *m_interpolator; } const GradientF& gradient_function() const { return *m_gradient_function; } - const ColorF color_function() const { return m_color_function; } - double d1() const { return double(m_d1) / gradient_subpixel_size; } - double d2() const { return double(m_d2) / gradient_subpixel_size; } + const ColorF& color_function() const { return *m_color_function; } + double d1() const { return double(m_d1) / gradient_subpixel_scale; } + double d2() const { return double(m_d2) / gradient_subpixel_scale; } //-------------------------------------------------------------------- void interpolator(interpolator_type& i) { m_interpolator = &i; } void gradient_function(const GradientF& gf) { m_gradient_function = &gf; } - void color_function(ColorF cf) { m_color_function = cf; } - void d1(double v) { m_d1 = int(v * gradient_subpixel_size); } - void d2(double v) { m_d2 = int(v * gradient_subpixel_size); } + void color_function(const ColorF& cf) { m_color_function = &cf; } + void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); } + void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); } //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) + void prepare() {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) { - color_type* span = base_type::allocator().span(); int dd = m_d2 - m_d1; if(dd < 1) dd = 1; m_interpolator->begin(x+0.5, y+0.5, len); @@ -99,21 +95,20 @@ namespace agg { m_interpolator->coordinates(&x, &y); int d = m_gradient_function->calculate(x >> downscale_shift, - y >> downscale_shift, dd); - d = ((d - m_d1) << base_shift) / dd; + y >> downscale_shift, m_d2); + d = ((d - m_d1) * (int)m_color_function->size()) / dd; if(d < 0) d = 0; - if(d > base_mask) d = base_mask; - *span++ = m_color_function[d]; + if(d >= (int)m_color_function->size()) d = m_color_function->size() - 1; + *span++ = (*m_color_function)[d]; ++(*m_interpolator); } while(--len); - return base_type::allocator().span(); } private: interpolator_type* m_interpolator; const GradientF* m_gradient_function; - ColorF m_color_function; + const ColorF* m_color_function; int m_d1; int m_d2; }; @@ -122,34 +117,32 @@ namespace agg //=====================================================gradient_linear_color - template + template struct gradient_linear_color { typedef ColorT color_type; - enum - { - base_shift = BaseShift, - base_size = 1 << base_shift, - base_mask = base_size - 1 - }; gradient_linear_color() {} - gradient_linear_color(const color_type& c1, const color_type& c2) : - m_c1(c1), m_c2(c2) {} + gradient_linear_color(const color_type& c1, const color_type& c2, + unsigned size = 256) : + m_c1(c1), m_c2(c2), m_size(size) {} + unsigned size() const { return m_size; } color_type operator [] (unsigned v) const { - return m_c1.gradient(m_c2, double(v) / double(base_mask)); + return m_c1.gradient(m_c2, double(v) / double(m_size - 1)); } - void colors(const color_type& c1, const color_type& c2) + void colors(const color_type& c1, const color_type& c2, unsigned size = 256) { m_c1 = c1; m_c2 = c2; + m_size = size; } color_type m_c1; color_type m_c2; + unsigned m_size; }; @@ -158,7 +151,7 @@ namespace agg { // Actually the same as radial. Just for compatibility public: - static int calculate(int x, int y, int) + static AGG_INLINE int calculate(int x, int y, int) { return int(fast_sqrt(x*x + y*y)); } @@ -169,7 +162,7 @@ namespace agg class gradient_radial { public: - static int calculate(int x, int y, int) + static AGG_INLINE int calculate(int x, int y, int) { return int(fast_sqrt(x*x + y*y)); } @@ -180,9 +173,9 @@ namespace agg class gradient_radial_d { public: - static int calculate(int x, int y, int) + static AGG_INLINE int calculate(int x, int y, int) { - return int(sqrt(double(x)*double(x) + double(y)*double(y))); + return uround(sqrt(double(x)*double(x) + double(y)*double(y))); } }; @@ -193,7 +186,7 @@ namespace agg public: //--------------------------------------------------------------------- gradient_radial_focus() : - m_radius(100 * gradient_subpixel_size), + m_radius(100 * gradient_subpixel_scale), m_focus_x(0), m_focus_y(0) { @@ -202,9 +195,9 @@ namespace agg //--------------------------------------------------------------------- gradient_radial_focus(double r, double fx, double fy) : - m_radius (int(r * gradient_subpixel_size)), - m_focus_x(int(fx * gradient_subpixel_size)), - m_focus_y(int(fy * gradient_subpixel_size)) + m_radius (iround(r * gradient_subpixel_scale)), + m_focus_x(iround(fx * gradient_subpixel_scale)), + m_focus_y(iround(fy * gradient_subpixel_scale)) { update_values(); } @@ -212,26 +205,26 @@ namespace agg //--------------------------------------------------------------------- void init(double r, double fx, double fy) { - m_radius = int(r * gradient_subpixel_size); - m_focus_x = int(fx * gradient_subpixel_size); - m_focus_y = int(fy * gradient_subpixel_size); + m_radius = iround(r * gradient_subpixel_scale); + m_focus_x = iround(fx * gradient_subpixel_scale); + m_focus_y = iround(fy * gradient_subpixel_scale); update_values(); } //--------------------------------------------------------------------- - double radius() const { return double(m_radius) / gradient_subpixel_size; } - double focus_x() const { return double(m_focus_x) / gradient_subpixel_size; } - double focus_y() const { return double(m_focus_y) / gradient_subpixel_size; } + double radius() const { return double(m_radius) / gradient_subpixel_scale; } + double focus_x() const { return double(m_focus_x) / gradient_subpixel_scale; } + double focus_y() const { return double(m_focus_y) / gradient_subpixel_scale; } //--------------------------------------------------------------------- - int calculate(int x, int y, int d) const + int calculate(int x, int y, int) const { double solution_x; double solution_y; // Special case to avoid divide by zero or very near zero //--------------------------------- - if(x == int(m_focus_x)) + if(x == iround(m_focus_x)) { solution_x = m_focus_x; solution_y = 0.0; @@ -274,14 +267,14 @@ namespace agg double cur_to_focus = double(x - m_focus_x) * double(x - m_focus_x) + double(y - m_focus_y) * double(y - m_focus_y); - return int(sqrt(cur_to_focus / int_to_focus) * d); + return iround(sqrt(cur_to_focus / int_to_focus) * m_radius); } private: //--------------------------------------------------------------------- void update_values() { - // For use in the quadractic equation + // For use in the quadratic equation //------------------------------- m_radius2 = double(m_radius) * double(m_radius); @@ -299,8 +292,8 @@ namespace agg // x = r cos theta, y = r sin theta //------------------------ double a = atan2(double(m_focus_y), double(m_focus_x)); - m_focus_x = int(r * cos(a)); - m_focus_y = int(r * sin(a)); + m_focus_x = iround(r * cos(a)); + m_focus_y = iround(r * sin(a)); } // Calculate the solution to be used in the case where x == focus_x @@ -337,7 +330,7 @@ namespace agg class gradient_diamond { public: - static int calculate(int x, int y, int) + static AGG_INLINE int calculate(int x, int y, int) { int ax = abs(x); int ay = abs(y); @@ -350,7 +343,7 @@ namespace agg class gradient_xy { public: - static int calculate(int x, int y, int d) + static AGG_INLINE int calculate(int x, int y, int d) { return abs(x) * abs(y) / d; } @@ -361,7 +354,7 @@ namespace agg class gradient_sqrt_xy { public: - static int calculate(int x, int y, int) + static AGG_INLINE int calculate(int x, int y, int) { return fast_sqrt(abs(x) * abs(y)); } @@ -372,9 +365,9 @@ namespace agg class gradient_conic { public: - static int calculate(int x, int y, int d) + static AGG_INLINE int calculate(int x, int y, int d) { - return int(fabs(atan2(double(y), double(x))) * double(d) / pi); + return uround(fabs(atan2(double(y), double(x))) * double(d) / pi); } }; @@ -386,7 +379,7 @@ namespace agg gradient_repeat_adaptor(const GradientF& gradient) : m_gradient(&gradient) {} - int calculate(int x, int y, int d) const + AGG_INLINE int calculate(int x, int y, int d) const { int ret = m_gradient->calculate(x, y, d) % d; if(ret < 0) ret += d; @@ -405,7 +398,7 @@ namespace agg gradient_reflect_adaptor(const GradientF& gradient) : m_gradient(&gradient) {} - int calculate(int x, int y, int d) const + AGG_INLINE int calculate(int x, int y, int d) const { int d2 = d << 1; int ret = m_gradient->calculate(x, y, d) % d2; diff --git a/headers/libs/agg/agg_span_gradient_alpha.h b/headers/libs/agg/agg_span_gradient_alpha.h index 19327c3dbf..e6ee216558 100644 --- a/headers/libs/agg/agg_span_gradient_alpha.h +++ b/headers/libs/agg/agg_span_gradient_alpha.h @@ -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,13 +30,10 @@ namespace agg public: typedef Interpolator interpolator_type; typedef ColorT color_type; - typedef typename color_type::alpha_type alpha_type; + typedef typename color_type::value_type alpha_type; - enum + enum downscale_shift_e { - base_shift = 8, - base_size = 1 << base_shift, - base_mask = base_size - 1, downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift }; @@ -47,31 +44,34 @@ namespace agg //-------------------------------------------------------------------- span_gradient_alpha(interpolator_type& inter, const GradientF& gradient_function, - AlphaF alpha_function, + const AlphaF& alpha_function, double d1, double d2) : m_interpolator(&inter), m_gradient_function(&gradient_function), - m_alpha_function(alpha_function), - m_d1(int(d1 * gradient_subpixel_size)), - m_d2(int(d2 * gradient_subpixel_size)) + m_alpha_function(&alpha_function), + m_d1(iround(d1 * gradient_subpixel_scale)), + m_d2(iround(d2 * gradient_subpixel_scale)) {} //-------------------------------------------------------------------- interpolator_type& interpolator() { return *m_interpolator; } const GradientF& gradient_function() const { return *m_gradient_function; } - const AlphaF alpha_function() const { return m_alpha_function; } - double d1() const { return double(m_d1) / gradient_subpixel_size; } - double d2() const { return double(m_d2) / gradient_subpixel_size; } + const AlphaF& alpha_function() const { return *m_alpha_function; } + double d1() const { return double(m_d1) / gradient_subpixel_scale; } + double d2() const { return double(m_d2) / gradient_subpixel_scale; } //-------------------------------------------------------------------- void interpolator(interpolator_type& i) { m_interpolator = &i; } void gradient_function(const GradientF& gf) { m_gradient_function = &gf; } - void alpha_function(AlphaF af) { m_alpha_function = af; } - void d1(double v) { m_d1 = int(v * gradient_subpixel_size); } - void d2(double v) { m_d2 = int(v * gradient_subpixel_size); } + void alpha_function(const AlphaF& af) { m_alpha_function = ⁡ } + void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); } + void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); } //-------------------------------------------------------------------- - void convert(color_type* span, int x, int y, unsigned len) + void prepare() {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) { int dd = m_d2 - m_d1; if(dd < 1) dd = 1; @@ -80,11 +80,11 @@ namespace agg { m_interpolator->coordinates(&x, &y); int d = m_gradient_function->calculate(x >> downscale_shift, - y >> downscale_shift, dd); - d = ((d - m_d1) << base_shift) / dd; + y >> downscale_shift, m_d2); + d = ((d - m_d1) * (int)m_alpha_function->size()) / dd; if(d < 0) d = 0; - if(d > base_mask) d = base_mask; - span->a = m_alpha_function[d]; + if(d >= (int)m_alpha_function->size()) d = m_alpha_function->size() - 1; + span->a = (*m_alpha_function)[d]; ++span; ++(*m_interpolator); } @@ -94,7 +94,7 @@ namespace agg private: interpolator_type* m_interpolator; const GradientF* m_gradient_function; - AlphaF m_alpha_function; + const AlphaF* m_alpha_function; int m_d1; int m_d2; }; @@ -103,7 +103,7 @@ namespace agg //=======================================================gradient_alpha_x template struct gradient_alpha_x { - typedef typename ColorT::alpha_type alpha_type; + typedef typename ColorT::value_type alpha_type; alpha_type operator [] (alpha_type x) const { return x; } }; diff --git a/headers/libs/agg/agg_span_image_filter.h b/headers/libs/agg/agg_span_image_filter.h index 5d90fca3df..47e2f44e3e 100644 --- a/headers/libs/agg/agg_span_image_filter.h +++ b/headers/libs/agg/agg_span_image_filter.h @@ -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,76 +21,65 @@ #include "agg_basics.h" #include "agg_image_filters.h" -#include "agg_rendering_buffer.h" -#include "agg_span_generator.h" - +#include "agg_span_interpolator_linear.h" namespace agg { - //--------------------------------------------------span_image_filter - template - class span_image_filter : public span_generator + //-------------------------------------------------------span_image_filter + template class span_image_filter { public: - typedef ColorT color_type; - typedef Allocator alloc_type; + typedef Source source_type; typedef Interpolator interpolator_type; - //---------------------------------------------------------------- - span_image_filter(alloc_type& alloc) : - span_generator(alloc) - {} - - //---------------------------------------------------------------- - span_image_filter(alloc_type& alloc, - const rendering_buffer& src, - const color_type& back_color, + //-------------------------------------------------------------------- + span_image_filter() {} + span_image_filter(source_type& src, interpolator_type& interpolator, - const image_filter_base* filter) : - span_generator(alloc), + const image_filter_lut* filter) : m_src(&src), - m_back_color(back_color), m_interpolator(&interpolator), m_filter(filter), m_dx_dbl(0.5), m_dy_dbl(0.5), - m_dx_int(image_subpixel_size / 2), - m_dy_int(image_subpixel_size / 2) + m_dx_int(image_subpixel_scale / 2), + m_dy_int(image_subpixel_scale / 2) {} + void attach(source_type& v) { m_src = &v; } - //---------------------------------------------------------------- - const rendering_buffer& source_image() const { return *m_src; } - const color_type& background_color() const { return m_back_color; } - const image_filter_base& filter() const { return *m_filter; } - int filter_dx_int() const { return m_dx_int; } - int filter_dy_int() const { return m_dy_int; } - double filter_dx_dbl() const { return m_dx_dbl; } - double filter_dy_dbl() const { return m_dy_dbl; } + //-------------------------------------------------------------------- + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + const image_filter_lut& filter() const { return *m_filter; } + int filter_dx_int() const { return m_dx_int; } + int filter_dy_int() const { return m_dy_int; } + double filter_dx_dbl() const { return m_dx_dbl; } + double filter_dy_dbl() const { return m_dy_dbl; } - //---------------------------------------------------------------- - void source_image(const rendering_buffer& v) { m_src = &v; } - void background_color(const color_type& v) { m_back_color = v; } - void interpolator(interpolator_type& v) { m_interpolator = &v; } - void filter(const image_filter_base& v) { m_filter = &v; } + //-------------------------------------------------------------------- + void interpolator(interpolator_type& v) { m_interpolator = &v; } + void filter(const image_filter_lut& v) { m_filter = &v; } void filter_offset(double dx, double dy) { m_dx_dbl = dx; m_dy_dbl = dy; - m_dx_int = int(dx * image_subpixel_size); - m_dy_int = int(dy * image_subpixel_size); + m_dx_int = iround(dx * image_subpixel_scale); + m_dy_int = iround(dy * image_subpixel_scale); } void filter_offset(double d) { filter_offset(d, d); } - //---------------------------------------------------------------- + //-------------------------------------------------------------------- interpolator_type& interpolator() { return *m_interpolator; } - //---------------------------------------------------------------- + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- private: - const rendering_buffer* m_src; - color_type m_back_color; - interpolator_type* m_interpolator; - const image_filter_base* m_filter; + source_type* m_src; + interpolator_type* m_interpolator; + const image_filter_lut* m_filter; double m_dx_dbl; double m_dy_dbl; unsigned m_dx_int; @@ -99,64 +88,159 @@ namespace agg - //-------------------------------------------------remainder_unsigned - class remainder_unsigned + + //==============================================span_image_resample_affine + template + class span_image_resample_affine : + public span_image_filter > { public: - remainder_unsigned(unsigned size) : - m_size(size), - m_add(size * (0x3FFFFFFF / size)) + typedef Source source_type; + typedef span_interpolator_linear interpolator_type; + typedef span_image_filter base_type; + + //-------------------------------------------------------------------- + span_image_resample_affine() : + m_scale_limit(200.0), + m_blur_x(1.0), + m_blur_y(1.0) {} - unsigned operator () (int v) const - { - return (unsigned(v) + m_add) % m_size; - } - private: - unsigned m_size; - unsigned m_add; - }; + //-------------------------------------------------------------------- + span_image_resample_affine(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, &filter), + m_scale_limit(200.0), + m_blur_x(1.0), + m_blur_y(1.0) + {} - //----------------------------------------------------remainder_pow2 - class remainder_pow2 - { - public: - remainder_pow2(unsigned size) + //-------------------------------------------------------------------- + int scale_limit() const { return uround(m_scale_limit); } + void scale_limit(int v) { m_scale_limit = v; } + + //-------------------------------------------------------------------- + double blur_x() const { return m_blur_x; } + double blur_y() const { return m_blur_y; } + void blur_x(double v) { m_blur_x = v; } + void blur_y(double v) { m_blur_y = v; } + void blur(double v) { m_blur_x = m_blur_y = v; } + + //-------------------------------------------------------------------- + void prepare() { - m_mask = 1; - while(m_mask < size) m_mask = (m_mask << 1) | 1; - m_mask >>= 1; + double scale_x; + double scale_y; + + base_type::interpolator().transformer().scaling_abs(&scale_x, &scale_y); + + if(scale_x * scale_y > m_scale_limit) + { + scale_x = scale_x * m_scale_limit / (scale_x * scale_y); + scale_y = scale_y * m_scale_limit / (scale_x * scale_y); + } + + if(scale_x < 1) scale_x = 1; + if(scale_y < 1) scale_y = 1; + + if(scale_x > m_scale_limit) scale_x = m_scale_limit; + if(scale_y > m_scale_limit) scale_y = m_scale_limit; + + scale_x *= m_blur_x; + scale_y *= m_blur_y; + + if(scale_x < 1) scale_x = 1; + if(scale_y < 1) scale_y = 1; + + m_rx = uround( scale_x * double(image_subpixel_scale)); + m_rx_inv = uround(1.0/scale_x * double(image_subpixel_scale)); + + m_ry = uround( scale_y * double(image_subpixel_scale)); + m_ry_inv = uround(1.0/scale_y * double(image_subpixel_scale)); } - unsigned operator () (int v) const { return unsigned(v) & m_mask; } + + protected: + int m_rx; + int m_ry; + int m_rx_inv; + int m_ry_inv; + private: - unsigned m_mask; + double m_scale_limit; + double m_blur_x; + double m_blur_y; }; - //-----------------------------------------------remainder_auto_pow2 - class remainder_auto_pow2 + + //=====================================================span_image_resample + template + class span_image_resample : + public span_image_filter { public: - remainder_auto_pow2(unsigned size) : - m_size(size), - m_add(size * (0x3FFFFFFF / size)), - m_mask((m_size & (m_size-1)) ? 0 : m_size-1) + typedef Source source_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_type; + + //-------------------------------------------------------------------- + span_image_resample() : + m_scale_limit(20), + m_blur_x(image_subpixel_scale), + m_blur_y(image_subpixel_scale) {} - unsigned operator () (int v) const - { - if(m_mask) return unsigned(v) & m_mask; - return (unsigned(v) + m_add) % m_size; + //-------------------------------------------------------------------- + span_image_resample(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, &filter), + m_scale_limit(20), + m_blur_x(image_subpixel_scale), + m_blur_y(image_subpixel_scale) + {} + + //-------------------------------------------------------------------- + int scale_limit() const { return m_scale_limit; } + void scale_limit(int v) { m_scale_limit = v; } + + //-------------------------------------------------------------------- + double blur_x() const { return double(m_blur_x) / double(image_subpixel_scale); } + double blur_y() const { return double(m_blur_y) / double(image_subpixel_scale); } + void blur_x(double v) { m_blur_x = uround(v * double(image_subpixel_scale)); } + void blur_y(double v) { m_blur_y = uround(v * double(image_subpixel_scale)); } + void blur(double v) { m_blur_x = + m_blur_y = uround(v * double(image_subpixel_scale)); } + + protected: + AGG_INLINE void adjust_scale(int* rx, int* ry) + { + if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; + if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; + if(*rx > image_subpixel_scale * m_scale_limit) + { + *rx = image_subpixel_scale * m_scale_limit; + } + if(*ry > image_subpixel_scale * m_scale_limit) + { + *ry = image_subpixel_scale * m_scale_limit; + } + *rx = (*rx * m_blur_x) >> image_subpixel_shift; + *ry = (*ry * m_blur_y) >> image_subpixel_shift; + if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; + if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; } - private: - unsigned m_size; - unsigned m_add; - unsigned m_mask; + int m_scale_limit; + int m_blur_x; + int m_blur_y; }; + + } #endif diff --git a/headers/libs/agg/agg_span_image_filter_gray.h b/headers/libs/agg/agg_span_image_filter_gray.h new file mode 100644 index 0000000000..9f3ede78f2 --- /dev/null +++ b/headers/libs/agg/agg_span_image_filter_gray.h @@ -0,0 +1,748 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_SPAN_IMAGE_FILTER_GRAY_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_GRAY_INCLUDED + +#include "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_span_image_filter.h" + + +namespace agg +{ + + //==============================================span_image_filter_gray_nn + template + class span_image_filter_gray_nn : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_gray_nn() {} + span_image_filter_gray_nn(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + do + { + base_type::interpolator().coordinates(&x, &y); + span->v = *(const value_type*) + base_type::source().span(x >> image_subpixel_shift, + y >> image_subpixel_shift, + 1); + span->a = base_mask; + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //=========================================span_image_filter_gray_bilinear + template + class span_image_filter_gray_bilinear : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_gray_bilinear() {} + span_image_filter_gray_bilinear(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + calc_type fg; + const value_type *fg_ptr; + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + fg = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + fg += *fg_ptr * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr); + + fg_ptr = (const value_type*)base_type::source().next_x(); + fg += *fg_ptr * x_hr * (image_subpixel_scale - y_hr); + + fg_ptr = (const value_type*)base_type::source().next_y(); + fg += *fg_ptr * (image_subpixel_scale - x_hr) * y_hr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + fg += *fg_ptr * x_hr * y_hr; + + span->v = value_type(fg >> (image_subpixel_shift * 2)); + span->a = base_mask; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + //====================================span_image_filter_gray_bilinear_clip + template + class span_image_filter_gray_bilinear_clip : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_gray_bilinear_clip() {} + span_image_filter_gray_bilinear_clip(source_type& src, + const color_type& back_color, + interpolator_type& inter) : + base_type(src, inter, 0), + m_back_color(back_color) + {} + const color_type& background_color() const { return m_back_color; } + void background_color(const color_type& v) { m_back_color = v; } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + calc_type fg; + calc_type src_alpha; + value_type back_v = m_back_color.v; + value_type back_a = m_back_color.a; + + const value_type *fg_ptr; + + int maxx = base_type::source().width() - 1; + int maxy = base_type::source().height() - 1; + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + if(x_lr >= 0 && y_lr >= 0 && + x_lr < maxx && y_lr < maxy) + { + fg = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr; + + fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr); + fg += *fg_ptr++ * (image_subpixel_scale - y_hr) * x_hr; + + ++y_lr; + fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr; + + fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * y_hr; + fg += *fg_ptr++ * x_hr * y_hr; + + fg >>= image_subpixel_shift * 2; + src_alpha = base_mask; + } + else + { + unsigned weight; + if(x_lr < -1 || y_lr < -1 || + x_lr > maxx || y_lr > maxy) + { + fg = back_v; + src_alpha = back_a; + } + else + { + fg = + src_alpha = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * base_mask; + } + else + { + fg += back_v * weight; + src_alpha += back_a * weight; + } + + x_lr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * base_mask; + } + else + { + fg += back_v * weight; + src_alpha += back_a * weight; + } + + x_lr--; + y_lr++; + + weight = (image_subpixel_scale - x_hr) * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * base_mask; + } + else + { + fg += back_v * weight; + src_alpha += back_a * weight; + } + + x_lr++; + + weight = x_hr * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * base_mask; + } + else + { + fg += back_v * weight; + src_alpha += back_a * weight; + } + + fg >>= image_subpixel_shift * 2; + src_alpha >>= image_subpixel_shift * 2; + } + } + + span->v = (value_type)fg; + span->a = (value_type)src_alpha; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + private: + color_type m_back_color; + }; + + + + //==============================================span_image_filter_gray_2x2 + template + class span_image_filter_gray_2x2 : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_gray_2x2() {} + span_image_filter_gray_2x2(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + calc_type fg; + + const value_type *fg_ptr; + const int16* weight_array = base_type::filter().weight_array() + + ((base_type::filter().diameter()/2 - 1) << + image_subpixel_shift); + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + fg = image_filter_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg >>= image_filter_shift; + if(fg > base_mask) fg = base_mask; + + span->v = (value_type)fg; + span->a = base_mask; + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //==================================================span_image_filter_gray + template + class span_image_filter_gray : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_gray() {} + span_image_filter_gray(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + int fg; + const value_type *fg_ptr; + + unsigned diameter = base_type::filter().diameter(); + int start = base_type::filter().start(); + const int16* weight_array = base_type::filter().weight_array(); + + int x_count; + int weight_y; + + do + { + base_type::interpolator().coordinates(&x, &y); + + x -= base_type::filter_dx_int(); + y -= base_type::filter_dy_int(); + + int x_hr = x; + int y_hr = y; + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + fg = image_filter_scale / 2; + + int x_fract = x_hr & image_subpixel_mask; + unsigned y_count = diameter; + + y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); + fg_ptr = (const value_type*)base_type::source().span(x_lr + start, + y_lr + start, + diameter); + for(;;) + { + x_count = diameter; + weight_y = weight_array[y_hr]; + x_hr = image_subpixel_mask - x_fract; + for(;;) + { + fg += *fg_ptr * + ((weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + image_filter_shift); + if(--x_count == 0) break; + x_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + + if(--y_count == 0) break; + y_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg >>= image_filter_shift; + if(fg < 0) fg = 0; + if(fg > base_mask) fg = base_mask; + span->v = (value_type)fg; + span->a = base_mask; + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //=========================================span_image_resample_gray_affine + template + class span_image_resample_gray_affine : + public span_image_resample_affine + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef span_image_resample_affine base_type; + typedef typename base_type::interpolator_type interpolator_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask, + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_gray_affine() {} + span_image_resample_gray_affine(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + int radius_x = (diameter * base_type::m_rx) >> 1; + int radius_y = (diameter * base_type::m_ry) >> 1; + int len_x_lr = + (diameter * base_type::m_rx + image_subpixel_mask) >> + image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + + do + { + base_type::interpolator().coordinates(&x, &y); + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg = image_filter_scale / 2; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + base_type::m_ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + base_type::m_rx_inv) >> + image_subpixel_shift; + + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + + fg += *fg_ptr * weight; + total_weight += weight; + x_hr += base_type::m_rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += base_type::m_ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg /= total_weight; + if(fg < 0) fg = 0; + if(fg > base_mask) fg = base_mask; + + span->v = (value_type)fg; + span->a = base_mask; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //================================================span_image_resample_gray + template + class span_image_resample_gray : + public span_image_resample + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_resample base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask, + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_gray() {} + span_image_resample_gray(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + do + { + int rx; + int ry; + int rx_inv = image_subpixel_scale; + int ry_inv = image_subpixel_scale; + base_type::interpolator().coordinates(&x, &y); + base_type::interpolator().local_scale(&rx, &ry); + base_type::adjust_scale(&rx, &ry); + + rx_inv = image_subpixel_scale * image_subpixel_scale / rx; + ry_inv = image_subpixel_scale * image_subpixel_scale / ry; + + int radius_x = (diameter * rx) >> 1; + int radius_y = (diameter * ry) >> 1; + int len_x_lr = + (diameter * rx + image_subpixel_mask) >> + image_subpixel_shift; + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg = image_filter_scale / 2; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + rx_inv) >> + image_subpixel_shift; + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + fg += *fg_ptr * weight; + total_weight += weight; + x_hr += rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg /= total_weight; + if(fg < 0) fg = 0; + if(fg > base_mask) fg = base_mask; + + span->v = (value_type)fg; + span->a = base_mask; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + +} + + +#endif + + + diff --git a/headers/libs/agg/agg_span_image_filter_rgb.h b/headers/libs/agg/agg_span_image_filter_rgb.h new file mode 100644 index 0000000000..a72ffd2406 --- /dev/null +++ b/headers/libs/agg/agg_span_image_filter_rgb.h @@ -0,0 +1,892 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_SPAN_IMAGE_FILTER_RGB_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_span_image_filter.h" + + +namespace agg +{ + + //===============================================span_image_filter_rgb_nn + template + class span_image_filter_rgb_nn : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgb_nn() {} + span_image_filter_rgb_nn(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + do + { + base_type::interpolator().coordinates(&x, &y); + const value_type* fg_ptr = (const value_type*) + base_type::source().span(x >> image_subpixel_shift, + y >> image_subpixel_shift, + 1); + span->r = fg_ptr[order_type::R]; + span->g = fg_ptr[order_type::G]; + span->b = fg_ptr[order_type::B]; + span->a = base_mask; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //==========================================span_image_filter_rgb_bilinear + template + class span_image_filter_rgb_bilinear : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgb_bilinear() {} + span_image_filter_rgb_bilinear(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + calc_type fg[3]; + const value_type *fg_ptr; + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + + fg[0] = + fg[1] = + fg[2] = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + span->r = value_type(fg[order_type::R] >> (image_subpixel_shift * 2)); + span->g = value_type(fg[order_type::G] >> (image_subpixel_shift * 2)); + span->b = value_type(fg[order_type::B] >> (image_subpixel_shift * 2)); + span->a = base_mask; + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //=====================================span_image_filter_rgb_bilinear_clip + template + class span_image_filter_rgb_bilinear_clip : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgb_bilinear_clip() {} + span_image_filter_rgb_bilinear_clip(source_type& src, + const color_type& back_color, + interpolator_type& inter) : + base_type(src, inter, 0), + m_back_color(back_color) + {} + const color_type& background_color() const { return m_back_color; } + void background_color(const color_type& v) { m_back_color = v; } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + calc_type fg[3]; + calc_type src_alpha; + value_type back_r = m_back_color.r; + value_type back_g = m_back_color.g; + value_type back_b = m_back_color.b; + value_type back_a = m_back_color.a; + + const value_type *fg_ptr; + + int maxx = base_type::source().width() - 1; + int maxy = base_type::source().height() - 1; + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + unsigned weight; + + if(x_lr >= 0 && y_lr >= 0 && + x_lr < maxx && y_lr < maxy) + { + fg[0] = + fg[1] = + fg[2] = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + + ++y_lr; + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + + fg[0] >>= image_subpixel_shift * 2; + fg[1] >>= image_subpixel_shift * 2; + fg[2] >>= image_subpixel_shift * 2; + src_alpha = base_mask; + } + else + { + if(x_lr < -1 || y_lr < -1 || + x_lr > maxx || y_lr > maxy) + { + fg[order_type::R] = back_r; + fg[order_type::G] = back_g; + fg[order_type::B] = back_b; + src_alpha = back_a; + } + else + { + fg[0] = + fg[1] = + fg[2] = + src_alpha = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + src_alpha += weight * base_mask; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + src_alpha += back_a * weight; + } + + x_lr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + src_alpha += weight * base_mask; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + src_alpha += back_a * weight; + } + + x_lr--; + y_lr++; + + weight = (image_subpixel_scale - x_hr) * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + src_alpha += weight * base_mask; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + src_alpha += back_a * weight; + } + + x_lr++; + + weight = x_hr * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + src_alpha += weight * base_mask; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + src_alpha += back_a * weight; + } + + fg[0] >>= image_subpixel_shift * 2; + fg[1] >>= image_subpixel_shift * 2; + fg[2] >>= image_subpixel_shift * 2; + src_alpha >>= image_subpixel_shift * 2; + } + } + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)src_alpha; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + private: + color_type m_back_color; + }; + + + + //===============================================span_image_filter_rgb_2x2 + template + class span_image_filter_rgb_2x2 : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgb_2x2() {} + span_image_filter_rgb_2x2(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + calc_type fg[3]; + + const value_type *fg_ptr; + const int16* weight_array = base_type::filter().weight_array() + + ((base_type::filter().diameter()/2 - 1) << + image_subpixel_shift); + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + fg[0] = fg[1] = fg[2] = image_filter_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg[0] >>= image_filter_shift; + fg[1] >>= image_filter_shift; + fg[2] >>= image_filter_shift; + + if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask; + if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask; + if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = base_mask; + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //===================================================span_image_filter_rgb + template + class span_image_filter_rgb : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgb() {} + span_image_filter_rgb(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + int fg[3]; + const value_type *fg_ptr; + + unsigned diameter = base_type::filter().diameter(); + int start = base_type::filter().start(); + const int16* weight_array = base_type::filter().weight_array(); + + int x_count; + int weight_y; + + do + { + base_type::interpolator().coordinates(&x, &y); + + x -= base_type::filter_dx_int(); + y -= base_type::filter_dy_int(); + + int x_hr = x; + int y_hr = y; + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + fg[0] = fg[1] = fg[2] = image_filter_scale / 2; + + int x_fract = x_hr & image_subpixel_mask; + unsigned y_count = diameter; + + y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); + fg_ptr = (const value_type*)base_type::source().span(x_lr + start, + y_lr + start, + diameter); + for(;;) + { + x_count = diameter; + weight_y = weight_array[y_hr]; + x_hr = image_subpixel_mask - x_fract; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + image_filter_shift; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + if(--x_count == 0) break; + x_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + + if(--y_count == 0) break; + y_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] >>= image_filter_shift; + fg[1] >>= image_filter_shift; + fg[2] >>= image_filter_shift; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + + if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask; + if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask; + if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = base_mask; + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //==========================================span_image_resample_rgb_affine + template + class span_image_resample_rgb_affine : + public span_image_resample_affine + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef span_image_resample_affine base_type; + typedef typename base_type::interpolator_type interpolator_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask, + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgb_affine() {} + span_image_resample_rgb_affine(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[3]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + int radius_x = (diameter * base_type::m_rx) >> 1; + int radius_y = (diameter * base_type::m_ry) >> 1; + int len_x_lr = + (diameter * base_type::m_rx + image_subpixel_mask) >> + image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + + do + { + base_type::interpolator().coordinates(&x, &y); + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = image_filter_scale / 2; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + base_type::m_ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + base_type::m_rx_inv) >> + image_subpixel_shift; + + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + + fg[0] += *fg_ptr++ * weight; + fg[1] += *fg_ptr++ * weight; + fg[2] += *fg_ptr * weight; + total_weight += weight; + x_hr += base_type::m_rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += base_type::m_ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] /= total_weight; + fg[1] /= total_weight; + fg[2] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + + if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask; + if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask; + if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = base_mask; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //=================================================span_image_resample_rgb + template + class span_image_resample_rgb : + public span_image_resample + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_resample base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask, + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgb() {} + span_image_resample_rgb(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg[3]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + do + { + int rx; + int ry; + int rx_inv = image_subpixel_scale; + int ry_inv = image_subpixel_scale; + base_type::interpolator().coordinates(&x, &y); + base_type::interpolator().local_scale(&rx, &ry); + base_type::adjust_scale(&rx, &ry); + + rx_inv = image_subpixel_scale * image_subpixel_scale / rx; + ry_inv = image_subpixel_scale * image_subpixel_scale / ry; + + int radius_x = (diameter * rx) >> 1; + int radius_y = (diameter * ry) >> 1; + int len_x_lr = + (diameter * rx + image_subpixel_mask) >> + image_subpixel_shift; + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = image_filter_scale / 2; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + rx_inv) >> + image_subpixel_shift; + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + fg[0] += *fg_ptr++ * weight; + fg[1] += *fg_ptr++ * weight; + fg[2] += *fg_ptr * weight; + total_weight += weight; + x_hr += rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] /= total_weight; + fg[1] /= total_weight; + fg[2] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + + if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask; + if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask; + if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = base_mask; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + +} + + +#endif + + + diff --git a/headers/libs/agg/agg_span_image_filter_rgb24.h b/headers/libs/agg/agg_span_image_filter_rgb24.h deleted file mode 100644 index efc4931cff..0000000000 --- a/headers/libs/agg/agg_span_image_filter_rgb24.h +++ /dev/null @@ -1,539 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_SPAN_IMAGE_FILTER_RGB24_INCLUDED -#define AGG_SPAN_IMAGE_FILTER_RGB24_INCLUDED - -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_span_image_filter.h" - - -namespace agg -{ - - - //==============================================span_image_filter_rgb24_nn - template > - class span_image_filter_rgb24_nn : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - - //-------------------------------------------------------------------- - span_image_filter_rgb24_nn(alloc_type& alloc) : base_type(alloc) {} - - //-------------------------------------------------------------------- - span_image_filter_rgb24_nn(alloc_type& alloc, - const rendering_buffer& src, - const color_type& back_color, - interpolator_type& inter) : - base_type(alloc, src, back_color, inter, 0) - {} - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - - int fg[3]; - int src_alpha; - - const unsigned char *fg_ptr; - color_type* span = base_type::allocator().span(); - - int maxx = base_type::source_image().width() - 1; - int maxy = base_type::source_image().height() - 1; - - do - { - base_type::interpolator().coordinates(&x, &y); - - x >>= image_subpixel_shift; - y >>= image_subpixel_shift; - - if(x >= 0 && y >= 0 && - x <= maxx && y <= maxy) - { - fg_ptr = base_type::source_image().row(y) + x + x + x; - fg[0] = *fg_ptr++; - fg[1] = *fg_ptr++; - fg[2] = *fg_ptr++; - src_alpha = 255; - } - else - { - fg[Order::R] = base_type::background_color().r; - fg[Order::G] = base_type::background_color().g; - fg[Order::B] = base_type::background_color().b; - src_alpha = base_type::background_color().a; - } - - span->r = (int8u)fg[Order::R]; - span->g = (int8u)fg[Order::G]; - span->b = (int8u)fg[Order::B]; - span->a = (int8u)src_alpha; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - }; - - - - - //=========================================span_image_filter_rgb24_bilinear - template > - class span_image_filter_rgb24_bilinear : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - - //-------------------------------------------------------------------- - span_image_filter_rgb24_bilinear(alloc_type& alloc) : base_type(alloc) {} - - //-------------------------------------------------------------------- - span_image_filter_rgb24_bilinear(alloc_type& alloc, - const rendering_buffer& src, - const color_type& back_color, - interpolator_type& inter) : - base_type(alloc, src, back_color, inter, 0) - {} - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - int fg[3]; - int src_alpha; - int back_r = base_type::background_color().r; - int back_g = base_type::background_color().g; - int back_b = base_type::background_color().b; - int back_a = base_type::background_color().a; - - const unsigned char *fg_ptr; - - int stride = base_type::source_image().stride() - 2 * 3; - color_type* span = base_type::allocator().span(); - - int maxx = base_type::source_image().width() - 1; - int maxy = base_type::source_image().height() - 1; - - do - { - int x_hr; - int y_hr; - - base_type::interpolator().coordinates(&x_hr, &y_hr); - - x_hr -= base_type::filter_dx_int(); - y_hr -= base_type::filter_dy_int(); - - int x_lr = x_hr >> image_subpixel_shift; - int y_lr = y_hr >> image_subpixel_shift; - int weight; - - if(x_lr >= 0 && y_lr >= 0 && - x_lr < maxx && y_lr < maxy) - { - fg[0] = - fg[1] = - fg[2] = image_subpixel_size * image_subpixel_size / 2; - - x_hr &= image_subpixel_mask; - y_hr &= image_subpixel_mask; - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - - weight = (image_subpixel_size - x_hr) * - (image_subpixel_size - y_hr); - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - - weight = x_hr * (image_subpixel_size - y_hr); - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - - fg_ptr += stride; - - weight = (image_subpixel_size - x_hr) * y_hr; - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - - weight = x_hr * y_hr; - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - src_alpha = 255; - } - else - { - if(x_lr < -1 || y_lr < -1 || - x_lr > maxx || y_lr > maxy) - { - fg[Order::R] = back_r; - fg[Order::G] = back_g; - fg[Order::B] = back_b; - src_alpha = back_a; - } - else - { - fg[0] = - fg[1] = - fg[2] = - src_alpha = image_subpixel_size * image_subpixel_size / 2; - - x_hr &= image_subpixel_mask; - y_hr &= image_subpixel_mask; - - weight = (image_subpixel_size - x_hr) * - (image_subpixel_size - y_hr); - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - src_alpha += weight * 255; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - - x_lr++; - - weight = x_hr * (image_subpixel_size - y_hr); - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - src_alpha += weight * 255; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - - x_lr--; - y_lr++; - - weight = (image_subpixel_size - x_hr) * y_hr; - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - src_alpha += weight * 255; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - - x_lr++; - - weight = x_hr * y_hr; - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - src_alpha += weight * 255; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - src_alpha >>= image_subpixel_shift * 2; - } - } - - span->r = (int8u)fg[Order::R]; - span->g = (int8u)fg[Order::G]; - span->b = (int8u)fg[Order::B]; - span->a = (int8u)src_alpha; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - }; - - - - - - //=================================================span_image_filter_rgb24 - template > - class span_image_filter_rgb24 : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - - //-------------------------------------------------------------------- - span_image_filter_rgb24(alloc_type& alloc) : base_type(alloc) {} - - //-------------------------------------------------------------------- - span_image_filter_rgb24(alloc_type& alloc, - const rendering_buffer& src, - const color_type& back_color, - interpolator_type& inter, - const image_filter_base& filter) : - base_type(alloc, src, back_color, inter, &filter) - {} - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - - int fg[3]; - int src_alpha; - int back_r = base_type::background_color().r; - int back_g = base_type::background_color().g; - int back_b = base_type::background_color().b; - int back_a = base_type::background_color().a; - - const unsigned char *fg_ptr; - - unsigned dimension = base_type::filter().dimension(); - int start = base_type::filter().start(); - int start1 = start - 1; - const int* weight_array = base_type::filter().weight_array_int(); - - int stride = base_type::source_image().stride() - dimension * 3; - color_type* span = base_type::allocator().span(); - - int maxx = base_type::source_image().width() + start - 2; - int maxy = base_type::source_image().height() + start - 2; - - int maxx2 = base_type::source_image().width() - start - 1; - int maxy2 = base_type::source_image().height() - start - 1; - - int x_count; - int weight_y; - - do - { - base_type::interpolator().coordinates(&x, &y); - - x -= base_type::filter_dx_int(); - y -= base_type::filter_dy_int(); - - int x_hr = x; - int y_hr = y; - - int x_lr = x_hr >> image_subpixel_shift; - int y_lr = y_hr >> image_subpixel_shift; - - fg[0] = fg[1] = fg[2] = image_filter_size / 2; - - int x_fract = x_hr & image_subpixel_mask; - unsigned y_count = dimension; - - if(x_lr >= -start && y_lr >= -start && - x_lr <= maxx && y_lr <= maxy) - { - y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); - fg_ptr = base_type::source_image().row(y_lr + start) + (x_lr + start) * 3; - do - { - x_count = dimension; - weight_y = weight_array[y_hr]; - x_hr = image_subpixel_mask - x_fract; - - do - { - int weight = (weight_y * weight_array[x_hr] + - image_filter_size / 2) >> - image_filter_shift; - - fg[0] += *fg_ptr++ * weight; - fg[1] += *fg_ptr++ * weight; - fg[2] += *fg_ptr++ * weight; - - x_hr += image_subpixel_size; - - } while(--x_count); - - y_hr += image_subpixel_size; - fg_ptr += stride; - - } while(--y_count); - - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; - - if(fg[0] < 0) fg[0] = 0; - if(fg[1] < 0) fg[1] = 0; - if(fg[2] < 0) fg[2] = 0; - - if(fg[0] > 255) fg[0] = 255; - if(fg[1] > 255) fg[1] = 255; - if(fg[2] > 255) fg[2] = 255; - src_alpha = 255; - } - else - { - if(x_lr < start1 || y_lr < start1 || - x_lr > maxx2 || y_lr > maxy2) - { - fg[Order::R] = back_r; - fg[Order::G] = back_g; - fg[Order::B] = back_b; - src_alpha = back_a; - } - else - { - src_alpha = image_filter_size / 2; - y_lr = (y >> image_subpixel_shift) + start; - y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); - - do - { - x_count = dimension; - weight_y = weight_array[y_hr]; - x_lr = (x >> image_subpixel_shift) + start; - x_hr = image_subpixel_mask - x_fract; - - do - { - int weight = (weight_y * weight_array[x_hr] + - image_filter_size / 2) >> - image_filter_shift; - - if(x_lr >= 0 && y_lr >= 0 && - x_lr < int(base_type::source_image().width()) && - y_lr < int(base_type::source_image().height())) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr * 3; - fg[0] += *fg_ptr++ * weight; - fg[1] += *fg_ptr++ * weight; - fg[2] += *fg_ptr++ * weight; - src_alpha += 255 * weight; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - x_hr += image_subpixel_size; - x_lr++; - - } while(--x_count); - - y_hr += image_subpixel_size; - y_lr++; - - } while(--y_count); - - - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; - src_alpha >>= image_filter_shift; - - if(fg[0] < 0) fg[0] = 0; - if(fg[1] < 0) fg[1] = 0; - if(fg[2] < 0) fg[2] = 0; - if(src_alpha < 0) src_alpha = 0; - - if(src_alpha > 255) src_alpha = 255; - if(fg[0] > src_alpha) fg[0] = src_alpha; - if(fg[1] > src_alpha) fg[1] = src_alpha; - if(fg[2] > src_alpha) fg[2] = src_alpha; - } - } - - span->r = (int8u)fg[Order::R]; - span->g = (int8u)fg[Order::G]; - span->b = (int8u)fg[Order::B]; - span->a = (int8u)src_alpha; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - }; - -} - - -#endif - - - diff --git a/headers/libs/agg/agg_span_image_filter_rgb24_gamma.h b/headers/libs/agg/agg_span_image_filter_rgb24_gamma.h deleted file mode 100644 index 8b1839e6dc..0000000000 --- a/headers/libs/agg/agg_span_image_filter_rgb24_gamma.h +++ /dev/null @@ -1,481 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_SPAN_IMAGE_FILTER_RGB24_GAMMA_INCLUDED -#define AGG_SPAN_IMAGE_FILTER_RGB24_GAMMA_INCLUDED - -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_span_image_filter.h" -#include "agg_gamma_lut.h" - - -namespace agg -{ - - - //===================================span_image_filter_rgb24_gamma_bilinear - template, - class Gamma = gamma_lut > - class span_image_filter_rgb24_gamma_bilinear : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - typedef Gamma gamma_type; - - //-------------------------------------------------------------------- - span_image_filter_rgb24_gamma_bilinear(alloc_type& alloc, - const gamma_type& g) : - base_type(alloc), - m_gamma(&g) - {} - - //-------------------------------------------------------------------- - span_image_filter_rgb24_gamma_bilinear(alloc_type& alloc, - const rendering_buffer& src, - const color_type& back_color, - interpolator_type& inter, - const gamma_type& g) : - base_type(alloc, src, back_color, inter, 0), - m_gamma(&g) - {} - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - int fg[3]; - int src_alpha; - int back_r = m_gamma->dir(base_type::background_color().r); - int back_g = m_gamma->dir(base_type::background_color().g); - int back_b = m_gamma->dir(base_type::background_color().b); - int back_a = base_type::background_color().a; - - const unsigned char *fg_ptr; - - int stride = base_type::source_image().stride() - 2 * 3; - color_type* span = base_type::allocator().span(); - - int maxx = base_type::source_image().width() - 1; - int maxy = base_type::source_image().height() - 1; - - do - { - int x_hr; - int y_hr; - - base_type::interpolator().coordinates(&x_hr, &y_hr); - - x_hr -= base_type::filter_dx_int(); - y_hr -= base_type::filter_dy_int(); - - int x_lr = x_hr >> image_subpixel_shift; - int y_lr = y_hr >> image_subpixel_shift; - int weight; - - if(x_lr >= 0 && y_lr >= 0 && - x_lr < maxx && y_lr < maxy) - { - fg[0] = - fg[1] = - fg[2] = image_subpixel_size * image_subpixel_size / 2; - - x_hr &= image_subpixel_mask; - y_hr &= image_subpixel_mask; - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - - weight = (image_subpixel_size - x_hr) * - (image_subpixel_size - y_hr); - fg[0] += weight * m_gamma->dir(*fg_ptr++); - fg[1] += weight * m_gamma->dir(*fg_ptr++); - fg[2] += weight * m_gamma->dir(*fg_ptr++); - - weight = x_hr * (image_subpixel_size - y_hr); - fg[0] += weight * m_gamma->dir(*fg_ptr++); - fg[1] += weight * m_gamma->dir(*fg_ptr++); - fg[2] += weight * m_gamma->dir(*fg_ptr++); - - fg_ptr += stride; - - weight = (image_subpixel_size - x_hr) * y_hr; - fg[0] += weight * m_gamma->dir(*fg_ptr++); - fg[1] += weight * m_gamma->dir(*fg_ptr++); - fg[2] += weight * m_gamma->dir(*fg_ptr++); - - weight = x_hr * y_hr; - fg[0] += weight * m_gamma->dir(*fg_ptr++); - fg[1] += weight * m_gamma->dir(*fg_ptr++); - fg[2] += weight * m_gamma->dir(*fg_ptr++); - - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - src_alpha = 255; - } - else - { - if(x_lr < -1 || y_lr < -1 || - x_lr > maxx || y_lr > maxy) - { - fg[Order::R] = back_r; - fg[Order::G] = back_g; - fg[Order::B] = back_b; - src_alpha = back_a; - } - else - { - fg[0] = - fg[1] = - fg[2] = - src_alpha = image_subpixel_size * image_subpixel_size / 2; - - x_hr &= image_subpixel_mask; - y_hr &= image_subpixel_mask; - - weight = (image_subpixel_size - x_hr) * - (image_subpixel_size - y_hr); - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - fg[0] += weight * m_gamma->dir(*fg_ptr++); - fg[1] += weight * m_gamma->dir(*fg_ptr++); - fg[2] += weight * m_gamma->dir(*fg_ptr++); - src_alpha += weight * 255; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - - x_lr++; - - weight = x_hr * (image_subpixel_size - y_hr); - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - fg[0] += weight * m_gamma->dir(*fg_ptr++); - fg[1] += weight * m_gamma->dir(*fg_ptr++); - fg[2] += weight * m_gamma->dir(*fg_ptr++); - src_alpha += weight * 255; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - - x_lr--; - y_lr++; - - weight = (image_subpixel_size - x_hr) * y_hr; - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - fg[0] += weight * m_gamma->dir(*fg_ptr++); - fg[1] += weight * m_gamma->dir(*fg_ptr++); - fg[2] += weight * m_gamma->dir(*fg_ptr++); - src_alpha += weight * 255; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - - x_lr++; - - weight = x_hr * y_hr; - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; - fg[0] += weight * m_gamma->dir(*fg_ptr++); - fg[1] += weight * m_gamma->dir(*fg_ptr++); - fg[2] += weight * m_gamma->dir(*fg_ptr++); - src_alpha += weight * 255; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - src_alpha >>= image_subpixel_shift * 2; - } - } - - span->r = (int8u)m_gamma->inv(fg[Order::R]); - span->g = (int8u)m_gamma->inv(fg[Order::G]); - span->b = (int8u)m_gamma->inv(fg[Order::B]); - span->a = (int8u)src_alpha; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - - private: - const gamma_type* m_gamma; - }; - - - - - - //============================================span_image_filter_rgb24_gamma - template, - class Gamma = gamma_lut > - class span_image_filter_rgb24_gamma : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - typedef Gamma gamma_type; - - //-------------------------------------------------------------------- - span_image_filter_rgb24_gamma(alloc_type& alloc, const gamma_type& g) : - base_type(alloc), - m_gamma(&g) - {} - - //-------------------------------------------------------------------- - span_image_filter_rgb24_gamma(alloc_type& alloc, - const rendering_buffer& src, - const color_type& back_color, - interpolator_type& inter, - const image_filter_base& filter, - const gamma_type& g) : - base_type(alloc, src, back_color, inter, &filter), - m_gamma(&g) - {} - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - int fg[3]; - int src_alpha; - int back_r = m_gamma->dir(base_type::background_color().r); - int back_g = m_gamma->dir(base_type::background_color().g); - int back_b = m_gamma->dir(base_type::background_color().b); - int back_a = base_type::background_color().a; - - const unsigned char *fg_ptr; - - unsigned dimension = base_type::filter().dimension(); - int start = base_type::filter().start(); - int start1 = start - 1; - const int* weight_array = base_type::filter().weight_array_int(); - - int stride = base_type::source_image().stride() - dimension * 3; - color_type* span = base_type::allocator().span(); - - int maxx = base_type::source_image().width() + start - 2; - int maxy = base_type::source_image().height() + start - 2; - - int maxx2 = base_type::source_image().width() - start - 1; - int maxy2 = base_type::source_image().height() - start - 1; - - int x_count; - int weight_y; - - do - { - base_type::interpolator().coordinates(&x, &y); - - x -= base_type::filter_dx_int(); - y -= base_type::filter_dy_int(); - - int x_hr = x; - int y_hr = y; - - int x_lr = x_hr >> image_subpixel_shift; - int y_lr = y_hr >> image_subpixel_shift; - - fg[0] = fg[1] = fg[2] = image_filter_size / 2; - - int x_fract = x_hr & image_subpixel_mask; - unsigned y_count = dimension; - - if(x_lr >= -start && y_lr >= -start && - x_lr <= maxx && y_lr <= maxy) - { - y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); - fg_ptr = base_type::source_image().row(y_lr + start) + (x_lr + start) * 3; - do - { - x_count = dimension; - weight_y = weight_array[y_hr]; - x_hr = image_subpixel_mask - x_fract; - - do - { - int weight = (weight_y * weight_array[x_hr] + - image_filter_size / 2) >> - image_filter_shift; - - fg[0] += m_gamma->dir(*fg_ptr++) * weight; - fg[1] += m_gamma->dir(*fg_ptr++) * weight; - fg[2] += m_gamma->dir(*fg_ptr++) * weight; - - x_hr += image_subpixel_size; - - } while(--x_count); - - y_hr += image_subpixel_size; - fg_ptr += stride; - - } while(--y_count); - - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; - - if(fg[0] < 0) fg[0] = 0; - if(fg[1] < 0) fg[1] = 0; - if(fg[2] < 0) fg[2] = 0; - - if(fg[0] > 255) fg[0] = 255; - if(fg[1] > 255) fg[1] = 255; - if(fg[2] > 255) fg[2] = 255; - src_alpha = 255; - } - else - { - if(x_lr < start1 || y_lr < start1 || - x_lr > maxx2 || y_lr > maxy2) - { - fg[Order::R] = back_r; - fg[Order::G] = back_g; - fg[Order::B] = back_b; - src_alpha = back_a; - } - else - { - src_alpha = image_filter_size / 2; - y_lr = (y >> image_subpixel_shift) + start; - y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); - - do - { - x_count = dimension; - weight_y = weight_array[y_hr]; - x_lr = (x >> image_subpixel_shift) + start; - x_hr = image_subpixel_mask - x_fract; - - do - { - int weight = (weight_y * weight_array[x_hr] + - image_filter_size / 2) >> - image_filter_shift; - - if(x_lr >= 0 && y_lr >= 0 && - x_lr < int(base_type::source_image().width()) && - y_lr < int(base_type::source_image().height())) - { - fg_ptr = base_type::source_image().row(y_lr) + x_lr * 3; - fg[0] += m_gamma->dir(*fg_ptr++) * weight; - fg[1] += m_gamma->dir(*fg_ptr++) * weight; - fg[2] += m_gamma->dir(*fg_ptr++) * weight; - src_alpha += 255 * weight; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - src_alpha += back_a * weight; - } - x_hr += image_subpixel_size; - x_lr++; - - } while(--x_count); - - y_hr += image_subpixel_size; - y_lr++; - - } while(--y_count); - - - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; - src_alpha >>= image_filter_shift; - - if(fg[0] < 0) fg[0] = 0; - if(fg[1] < 0) fg[1] = 0; - if(fg[2] < 0) fg[2] = 0; - if(src_alpha < 0) src_alpha = 0; - - if(fg[0] > 255) fg[0] = 255; - if(fg[1] > 255) fg[1] = 255; - if(fg[2] > 255) fg[2] = 255; - if(src_alpha > 255) src_alpha = 255; - } - } - - span->r = (int8u)m_gamma->inv(fg[Order::R]); - span->g = (int8u)m_gamma->inv(fg[Order::G]); - span->b = (int8u)m_gamma->inv(fg[Order::B]); - span->a = (int8u)src_alpha; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - - private: - const gamma_type* m_gamma; - }; - -} - - -#endif - - - diff --git a/headers/libs/agg/agg_span_image_filter_rgba.h b/headers/libs/agg/agg_span_image_filter_rgba.h new file mode 100644 index 0000000000..134a802550 --- /dev/null +++ b/headers/libs/agg/agg_span_image_filter_rgba.h @@ -0,0 +1,920 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_SPAN_IMAGE_FILTER_RGBA_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_RGBA_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_span_image_filter.h" + + +namespace agg +{ + + //==============================================span_image_filter_rgba_nn + template + class span_image_filter_rgba_nn : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgba_nn() {} + span_image_filter_rgba_nn(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + do + { + base_type::interpolator().coordinates(&x, &y); + const value_type* fg_ptr = (const value_type*) + base_type::source().span(x >> image_subpixel_shift, + y >> image_subpixel_shift, + 1); + span->r = fg_ptr[order_type::R]; + span->g = fg_ptr[order_type::G]; + span->b = fg_ptr[order_type::B]; + span->a = fg_ptr[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //=========================================span_image_filter_rgba_bilinear + template + class span_image_filter_rgba_bilinear : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgba_bilinear() {} + span_image_filter_rgba_bilinear(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + calc_type fg[4]; + const value_type *fg_ptr; + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + + fg[0] = + fg[1] = + fg[2] = + fg[3] = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + span->r = value_type(fg[order_type::R] >> (image_subpixel_shift * 2)); + span->g = value_type(fg[order_type::G] >> (image_subpixel_shift * 2)); + span->b = value_type(fg[order_type::B] >> (image_subpixel_shift * 2)); + span->a = value_type(fg[order_type::A] >> (image_subpixel_shift * 2)); + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + //====================================span_image_filter_rgba_bilinear_clip + template + class span_image_filter_rgba_bilinear_clip : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgba_bilinear_clip() {} + span_image_filter_rgba_bilinear_clip(source_type& src, + const color_type& back_color, + interpolator_type& inter) : + base_type(src, inter, 0), + m_back_color(back_color) + {} + const color_type& background_color() const { return m_back_color; } + void background_color(const color_type& v) { m_back_color = v; } + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + calc_type fg[4]; + value_type back_r = m_back_color.r; + value_type back_g = m_back_color.g; + value_type back_b = m_back_color.b; + value_type back_a = m_back_color.a; + + const value_type *fg_ptr; + int maxx = base_type::source().width() - 1; + int maxy = base_type::source().height() - 1; + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + + if(x_lr >= 0 && y_lr >= 0 && + x_lr < maxx && y_lr < maxy) + { + fg[0] = + fg[1] = + fg[2] = + fg[3] = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + ++y_lr; + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + fg[0] >>= image_subpixel_shift * 2; + fg[1] >>= image_subpixel_shift * 2; + fg[2] >>= image_subpixel_shift * 2; + fg[3] >>= image_subpixel_shift * 2; + } + else + { + if(x_lr < -1 || y_lr < -1 || + x_lr > maxx || y_lr > maxy) + { + fg[order_type::R] = back_r; + fg[order_type::G] = back_g; + fg[order_type::B] = back_b; + fg[order_type::A] = back_a; + } + else + { + fg[0] = + fg[1] = + fg[2] = + fg[3] = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + x_lr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + x_lr--; + y_lr++; + + weight = (image_subpixel_scale - x_hr) * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + x_lr++; + + weight = x_hr * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + fg[0] >>= image_subpixel_shift * 2; + fg[1] >>= image_subpixel_shift * 2; + fg[2] >>= image_subpixel_shift * 2; + fg[3] >>= image_subpixel_shift * 2; + } + } + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + private: + color_type m_back_color; + }; + + + //==============================================span_image_filter_rgba_2x2 + template + class span_image_filter_rgba_2x2 : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgba_2x2() {} + span_image_filter_rgba_2x2(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + calc_type fg[4]; + + const value_type *fg_ptr; + const int16* weight_array = base_type::filter().weight_array() + + ((base_type::filter().diameter()/2 - 1) << + image_subpixel_shift); + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg[0] >>= image_filter_shift; + fg[1] >>= image_filter_shift; + fg[2] >>= image_filter_shift; + fg[3] >>= image_filter_shift; + + if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask; + if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; + if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; + if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //==================================================span_image_filter_rgba + template + class span_image_filter_rgba : + public span_image_filter + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter base_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_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + span_image_filter_rgba() {} + span_image_filter_rgba(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + int fg[4]; + const value_type *fg_ptr; + + unsigned diameter = base_type::filter().diameter(); + int start = base_type::filter().start(); + const int16* weight_array = base_type::filter().weight_array(); + + int x_count; + int weight_y; + + do + { + base_type::interpolator().coordinates(&x, &y); + + x -= base_type::filter_dx_int(); + y -= base_type::filter_dy_int(); + + int x_hr = x; + int y_hr = y; + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2; + + int x_fract = x_hr & image_subpixel_mask; + unsigned y_count = diameter; + + y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); + fg_ptr = (const value_type*)base_type::source().span(x_lr + start, + y_lr + start, + diameter); + for(;;) + { + x_count = diameter; + weight_y = weight_array[y_hr]; + x_hr = image_subpixel_mask - x_fract; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + image_filter_shift; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + if(--x_count == 0) break; + x_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + + if(--y_count == 0) break; + y_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] >>= image_filter_shift; + fg[1] >>= image_filter_shift; + fg[2] >>= image_filter_shift; + fg[3] >>= image_filter_shift; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + if(fg[3] < 0) fg[3] = 0; + + if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask; + if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; + if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; + if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //========================================span_image_resample_rgba_affine + template + class span_image_resample_rgba_affine : + public span_image_resample_affine + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef span_image_resample_affine base_type; + typedef typename base_type::interpolator_type interpolator_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask, + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgba_affine() {} + span_image_resample_rgba_affine(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[4]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + int radius_x = (diameter * base_type::m_rx) >> 1; + int radius_y = (diameter * base_type::m_ry) >> 1; + int len_x_lr = + (diameter * base_type::m_rx + image_subpixel_mask) >> + image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + + do + { + base_type::interpolator().coordinates(&x, &y); + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + base_type::m_ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + base_type::m_rx_inv) >> + image_subpixel_shift; + + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + + fg[0] += *fg_ptr++ * weight; + fg[1] += *fg_ptr++ * weight; + fg[2] += *fg_ptr++ * weight; + fg[3] += *fg_ptr++ * weight; + total_weight += weight; + x_hr += base_type::m_rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += base_type::m_ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] /= total_weight; + fg[1] /= total_weight; + fg[2] /= total_weight; + fg[3] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + if(fg[3] < 0) fg[3] = 0; + + if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask; + if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; + if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; + if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //==============================================span_image_resample_rgba + template + class span_image_resample_rgba : + public span_image_resample + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_resample base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask, + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgba() {} + span_image_resample_rgba(source_type& src, + interpolator_type& inter, + const image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg[4]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + do + { + int rx; + int ry; + int rx_inv = image_subpixel_scale; + int ry_inv = image_subpixel_scale; + base_type::interpolator().coordinates(&x, &y); + base_type::interpolator().local_scale(&rx, &ry); + base_type::adjust_scale(&rx, &ry); + + rx_inv = image_subpixel_scale * image_subpixel_scale / rx; + ry_inv = image_subpixel_scale * image_subpixel_scale / ry; + + int radius_x = (diameter * rx) >> 1; + int radius_y = (diameter * ry) >> 1; + int len_x_lr = + (diameter * rx + image_subpixel_mask) >> + image_subpixel_shift; + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + rx_inv) >> + image_subpixel_shift; + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + fg[0] += *fg_ptr++ * weight; + fg[1] += *fg_ptr++ * weight; + fg[2] += *fg_ptr++ * weight; + fg[3] += *fg_ptr++ * weight; + total_weight += weight; + x_hr += rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] /= total_weight; + fg[1] /= total_weight; + fg[2] /= total_weight; + fg[3] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + if(fg[3] < 0) fg[3] = 0; + + if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask; + if(fg[order_type::R] > fg[order_type::R]) fg[order_type::R] = fg[order_type::R]; + if(fg[order_type::G] > fg[order_type::G]) fg[order_type::G] = fg[order_type::G]; + if(fg[order_type::B] > fg[order_type::B]) fg[order_type::B] = fg[order_type::B]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + +} + + +#endif + + + diff --git a/headers/libs/agg/agg_span_image_filter_rgba32.h b/headers/libs/agg/agg_span_image_filter_rgba32.h deleted file mode 100644 index 783f1bee5f..0000000000 --- a/headers/libs/agg/agg_span_image_filter_rgba32.h +++ /dev/null @@ -1,559 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes span_image_filter_rgba32* -// -//---------------------------------------------------------------------------- -#ifndef AGG_SPAN_IMAGE_FILTER_RGBA32_INCLUDED -#define AGG_SPAN_IMAGE_FILTER_RGBA32_INCLUDED - -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_span_image_filter.h" - - -namespace agg -{ - - //=============================================span_image_filter_rgba32_nn - template > - class span_image_filter_rgba32_nn : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - - //-------------------------------------------------------------------- - span_image_filter_rgba32_nn(alloc_type& alloc) : base_type(alloc) {} - - //-------------------------------------------------------------------- - span_image_filter_rgba32_nn(alloc_type& alloc, - const rendering_buffer& src, - const color_type& back_color, - interpolator_type& inter) : - base_type(alloc, src, back_color, inter, 0) - {} - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - - int fg[4]; - - const unsigned char *fg_ptr; - color_type* span = base_type::allocator().span(); - - int maxx = base_type::source_image().width() - 1; - int maxy = base_type::source_image().height() - 1; - - do - { - base_type::interpolator().coordinates(&x, &y); - - x >>= image_subpixel_shift; - y >>= image_subpixel_shift; - - if(x >= 0 && y >= 0 && - x <= maxx && y <= maxy) - { - fg_ptr = base_type::source_image().row(y) + (x << 2); - fg[0] = *fg_ptr++; - fg[1] = *fg_ptr++; - fg[2] = *fg_ptr++; - fg[3] = *fg_ptr++; - } - else - { - fg[Order::R] = base_type::background_color().r; - fg[Order::G] = base_type::background_color().g; - fg[Order::B] = base_type::background_color().b; - fg[Order::A] = base_type::background_color().a; - } - - span->r = fg[Order::R]; - span->g = fg[Order::G]; - span->b = fg[Order::B]; - span->a = fg[Order::A]; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - - }; - - - - - - - - - - - //=======================================span_image_filter_rgba32_bilinear - template > - class span_image_filter_rgba32_bilinear : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - - //-------------------------------------------------------------------- - span_image_filter_rgba32_bilinear(alloc_type& alloc) : base_type(alloc) {} - - //-------------------------------------------------------------------- - span_image_filter_rgba32_bilinear(alloc_type& alloc, - const rendering_buffer& src, - const color_type& back_color, - interpolator_type& inter) : - base_type(alloc, src, back_color, inter, 0) - {} - - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - - int fg[4]; - int back_r = base_type::background_color().r; - int back_g = base_type::background_color().g; - int back_b = base_type::background_color().b; - int back_a = base_type::background_color().a; - - const unsigned char *fg_ptr; - - int stride = base_type::source_image().stride() - 2 * 4; - color_type* span = base_type::allocator().span(); - - int maxx = base_type::source_image().width() - 1; - int maxy = base_type::source_image().height() - 1; - - do - { - int x_hr; - int y_hr; - - base_type::interpolator().coordinates(&x_hr, &y_hr); - - x_hr -= base_type::filter_dx_int(); - y_hr -= base_type::filter_dy_int(); - - int x_lr = x_hr >> image_subpixel_shift; - int y_lr = y_hr >> image_subpixel_shift; - - int weight; - - if(x_lr >= 0 && y_lr >= 0 && - x_lr < maxx && y_lr < maxy) - { - fg[0] = - fg[1] = - fg[2] = - fg[3] = image_subpixel_size * image_subpixel_size / 2; - - x_hr &= image_subpixel_mask; - y_hr &= image_subpixel_mask; - - fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); - - weight = (image_subpixel_size - x_hr) * - (image_subpixel_size - y_hr); - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - fg[3] += weight * *fg_ptr++; - - weight = x_hr * (image_subpixel_size - y_hr); - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - fg[3] += weight * *fg_ptr++; - - fg_ptr += stride; - - weight = (image_subpixel_size - x_hr) * y_hr; - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - fg[3] += weight * *fg_ptr++; - - weight = x_hr * y_hr; - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - fg[3] += weight * *fg_ptr++; - - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - fg[3] >>= image_subpixel_shift * 2; - } - else - { - if(x_lr < -1 || y_lr < -1 || - x_lr > maxx || y_lr > maxy) - { - fg[Order::R] = back_r; - fg[Order::G] = back_g; - fg[Order::B] = back_b; - fg[Order::A] = back_a; - } - else - { - fg[0] = - fg[1] = - fg[2] = - fg[3] = image_subpixel_size * image_subpixel_size / 2; - - x_hr &= image_subpixel_mask; - y_hr &= image_subpixel_mask; - - weight = (image_subpixel_size - x_hr) * - (image_subpixel_size - y_hr); - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - fg[3] += weight * *fg_ptr++; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - fg[Order::A] += back_a * weight; - } - - x_lr++; - - weight = x_hr * (image_subpixel_size - y_hr); - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - fg[3] += weight * *fg_ptr++; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - fg[Order::A] += back_a * weight; - } - - x_lr--; - y_lr++; - - weight = (image_subpixel_size - x_hr) * y_hr; - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - fg[3] += weight * *fg_ptr++; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - fg[Order::A] += back_a * weight; - } - - x_lr++; - - weight = x_hr * y_hr; - if(x_lr >= 0 && y_lr >= 0 && - x_lr <= maxx && y_lr <= maxy) - { - fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); - fg[0] += weight * *fg_ptr++; - fg[1] += weight * *fg_ptr++; - fg[2] += weight * *fg_ptr++; - fg[3] += weight * *fg_ptr++; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - fg[Order::A] += back_a * weight; - } - - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - fg[3] >>= image_subpixel_shift * 2; - } - } - - span->r = (int8u)fg[Order::R]; - span->g = (int8u)fg[Order::G]; - span->b = (int8u)fg[Order::B]; - span->a = (int8u)fg[Order::A]; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - }; - - - - - - //================================================span_image_filter_rgba32 - template > - class span_image_filter_rgba32 : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - - //-------------------------------------------------------------------- - span_image_filter_rgba32(alloc_type& alloc) : base_type(alloc) {} - - //-------------------------------------------------------------------- - span_image_filter_rgba32(alloc_type& alloc, - const rendering_buffer& src, - const color_type& back_color, - interpolator_type& inter, - const image_filter_base& filter) : - base_type(alloc, src, back_color, inter, &filter) - {} - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - - int fg[4]; - - int back_r = base_type::background_color().r; - int back_g = base_type::background_color().g; - int back_b = base_type::background_color().b; - int back_a = base_type::background_color().a; - - const unsigned char *fg_ptr; - - unsigned dimension = base_type::filter().dimension(); - int start = base_type::filter().start(); - int start1 = start - 1; - const int* weight_array = base_type::filter().weight_array_int(); - - int stride = base_type::source_image().stride() - (dimension << 2); - color_type* span = base_type::allocator().span(); - - int maxx = base_type::source_image().width() + start - 2; - int maxy = base_type::source_image().height() + start - 2; - - int maxx2 = base_type::source_image().width() - start - 1; - int maxy2 = base_type::source_image().height() - start - 1; - - int x_count; - int weight_y; - - do - { - base_type::interpolator().coordinates(&x, &y); - - x -= base_type::filter_dx_int(); - y -= base_type::filter_dy_int(); - - int x_hr = x; - int y_hr = y; - - int x_lr = x_hr >> image_subpixel_shift; - int y_lr = y_hr >> image_subpixel_shift; - - fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2; - - int x_fract = x_hr & image_subpixel_mask; - unsigned y_count = dimension; - - if(x_lr >= -start && y_lr >= -start && - x_lr <= maxx && y_lr <= maxy) - { - y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); - fg_ptr = base_type::source_image().row(y_lr + start) + ((x_lr + start) << 2); - do - { - x_count = dimension; - weight_y = weight_array[y_hr]; - x_hr = image_subpixel_mask - x_fract; - - do - { - int weight = (weight_y * weight_array[x_hr] + - image_filter_size / 2) >> - image_filter_shift; - - fg[0] += *fg_ptr++ * weight; - fg[1] += *fg_ptr++ * weight; - fg[2] += *fg_ptr++ * weight; - fg[3] += *fg_ptr++ * weight; - - x_hr += image_subpixel_size; - - } while(--x_count); - - y_hr += image_subpixel_size; - fg_ptr += stride; - - } while(--y_count); - - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; - fg[3] >>= image_filter_shift; - - if(fg[0] < 0) fg[0] = 0; - if(fg[1] < 0) fg[1] = 0; - if(fg[2] < 0) fg[2] = 0; - if(fg[3] < 0) fg[3] = 0; - - if(fg[Order::A] > 255) fg[Order::A] = 255; - if(fg[Order::R] > fg[Order::A]) fg[Order::R] = fg[Order::A]; - if(fg[Order::G] > fg[Order::A]) fg[Order::G] = fg[Order::A]; - if(fg[Order::B] > fg[Order::A]) fg[Order::B] = fg[Order::A]; - } - else - { - if(x_lr < start1 || y_lr < start1 || - x_lr > maxx2 || y_lr > maxy2) - { - fg[Order::R] = back_r; - fg[Order::G] = back_g; - fg[Order::B] = back_b; - fg[Order::A] = back_a; - } - else - { - y_lr = (y >> image_subpixel_shift) + start; - y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); - - do - { - x_count = dimension; - weight_y = weight_array[y_hr]; - x_lr = (x >> image_subpixel_shift) + start; - x_hr = image_subpixel_mask - x_fract; - - do - { - int weight = (weight_y * weight_array[x_hr] + - image_filter_size / 2) >> - image_filter_shift; - - if(x_lr >= 0 && y_lr >= 0 && - x_lr < int(base_type::source_image().width()) && - y_lr < int(base_type::source_image().height())) - { - fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); - fg[0] += *fg_ptr++ * weight; - fg[1] += *fg_ptr++ * weight; - fg[2] += *fg_ptr++ * weight; - fg[3] += *fg_ptr++ * weight; - } - else - { - fg[Order::R] += back_r * weight; - fg[Order::G] += back_g * weight; - fg[Order::B] += back_b * weight; - fg[Order::A] += back_a * weight; - } - x_hr += image_subpixel_size; - x_lr++; - - } while(--x_count); - - y_hr += image_subpixel_size; - y_lr++; - - } while(--y_count); - - - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; - fg[3] >>= image_filter_shift; - - if(fg[0] < 0) fg[0] = 0; - if(fg[1] < 0) fg[1] = 0; - if(fg[2] < 0) fg[2] = 0; - if(fg[3] < 0) fg[3] = 0; - - if(fg[Order::A] > 255) fg[Order::A] = 255; - if(fg[Order::R] > fg[Order::A]) fg[Order::R] = fg[Order::A]; - if(fg[Order::G] > fg[Order::A]) fg[Order::G] = fg[Order::A]; - if(fg[Order::B] > fg[Order::A]) fg[Order::B] = fg[Order::A]; - } - } - - span->r = fg[Order::R]; - span->g = fg[Order::G]; - span->b = fg[Order::B]; - span->a = fg[Order::A]; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - - }; - - -} - - -#endif - - - diff --git a/headers/libs/agg/agg_span_interpolator_adaptor.h b/headers/libs/agg/agg_span_interpolator_adaptor.h index b66e8997c7..17ea71291b 100644 --- a/headers/libs/agg/agg_span_interpolator_adaptor.h +++ b/headers/libs/agg/agg_span_interpolator_adaptor.h @@ -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. diff --git a/headers/libs/agg/agg_span_interpolator_linear.h b/headers/libs/agg/agg_span_interpolator_linear.h index 61af77a85e..cbf3d1a414 100644 --- a/headers/libs/agg/agg_span_interpolator_linear.h +++ b/headers/libs/agg/agg_span_interpolator_linear.h @@ -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,10 +30,10 @@ namespace agg public: typedef Transformer trans_type; - enum + enum subpixel_scale_e { subpixel_shift = SubpixelShift, - subpixel_size = 1 << subpixel_shift + subpixel_scale = 1 << subpixel_shift }; //-------------------------------------------------------------------- @@ -59,19 +59,27 @@ namespace agg tx = x; ty = y; m_trans->transform(&tx, &ty); - int x1 = int(tx * subpixel_size); - int y1 = int(ty * subpixel_size); + int x1 = iround(tx * subpixel_scale); + int y1 = iround(ty * subpixel_scale); tx = x + len; ty = y; m_trans->transform(&tx, &ty); - int x2 = int(tx * subpixel_size); - int y2 = int(ty * subpixel_size); + int x2 = iround(tx * subpixel_scale); + int y2 = iround(ty * subpixel_scale); m_li_x = dda2_line_interpolator(x1, x2, len); m_li_y = dda2_line_interpolator(y1, y2, len); } + //---------------------------------------------------------------- + void resynchronize(double xe, double ye, unsigned len) + { + m_trans->transform(&xe, &ye); + m_li_x = dda2_line_interpolator(m_li_x.y(), iround(xe * subpixel_scale), len); + m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ye * subpixel_scale), len); + } + //---------------------------------------------------------------- void operator++() { @@ -92,6 +100,129 @@ namespace agg dda2_line_interpolator m_li_y; }; + + + + + + //=====================================span_interpolator_linear_subdiv + template + class span_interpolator_linear_subdiv + { + public: + typedef Transformer trans_type; + + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + + //---------------------------------------------------------------- + span_interpolator_linear_subdiv() : + m_subdiv_shift(4), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1) {} + + span_interpolator_linear_subdiv(const trans_type& trans, + unsigned subdiv_shift = 4) : + m_subdiv_shift(subdiv_shift), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1), + m_trans(&trans) {} + + span_interpolator_linear_subdiv(const trans_type& trans, + double x, double y, unsigned len, + unsigned subdiv_shift = 4) : + m_subdiv_shift(subdiv_shift), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1), + m_trans(&trans) + { + begin(x, y, len); + } + + //---------------------------------------------------------------- + const trans_type& transformer() const { return *m_trans; } + void transformer(const trans_type& trans) { m_trans = &trans; } + + //---------------------------------------------------------------- + unsigned subdiv_shift() const { return m_subdiv_shift; } + void subdiv_shift(unsigned shift) + { + m_subdiv_shift = shift; + m_subdiv_size = 1 << m_subdiv_shift; + m_subdiv_mask = m_subdiv_size - 1; + } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + double tx; + double ty; + m_pos = 1; + m_src_x = iround(x * subpixel_scale) + subpixel_scale; + m_src_y = y; + m_len = len; + + if(len > m_subdiv_size) len = m_subdiv_size; + tx = x; + ty = y; + m_trans->transform(&tx, &ty); + int x1 = iround(tx * subpixel_scale); + int y1 = iround(ty * subpixel_scale); + + tx = x + len; + ty = y; + m_trans->transform(&tx, &ty); + + m_li_x = dda2_line_interpolator(x1, iround(tx * subpixel_scale), len); + m_li_y = dda2_line_interpolator(y1, iround(ty * subpixel_scale), len); + } + + //---------------------------------------------------------------- + void operator++() + { + ++m_li_x; + ++m_li_y; + if(m_pos >= m_subdiv_size) + { + unsigned len = m_len; + if(len > m_subdiv_size) len = m_subdiv_size; + double tx = double(m_src_x) / double(subpixel_scale) + len; + double ty = m_src_y; + m_trans->transform(&tx, &ty); + m_li_x = dda2_line_interpolator(m_li_x.y(), iround(tx * subpixel_scale), len); + m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ty * subpixel_scale), len); + m_pos = 0; + } + m_src_x += subpixel_scale; + ++m_pos; + --m_len; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = m_li_x.y(); + *y = m_li_y.y(); + } + + private: + unsigned m_subdiv_shift; + unsigned m_subdiv_size; + unsigned m_subdiv_mask; + const trans_type* m_trans; + dda2_line_interpolator m_li_x; + dda2_line_interpolator m_li_y; + int m_src_x; + double m_src_y; + unsigned m_pos; + unsigned m_len; + }; + + } diff --git a/headers/libs/agg/agg_span_interpolator_persp.h b/headers/libs/agg/agg_span_interpolator_persp.h new file mode 100644 index 0000000000..cad437e04f --- /dev/null +++ b/headers/libs/agg/agg_span_interpolator_persp.h @@ -0,0 +1,462 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED +#define AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED + +#include "agg_trans_perspective.h" +#include "agg_dda_line.h" + +namespace agg +{ + + + + //===========================================span_interpolator_persp_exact + template + class span_interpolator_persp_exact + { + public: + typedef trans_perspective trans_type; + typedef trans_perspective::iterator_x iterator_type; + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + //-------------------------------------------------------------------- + span_interpolator_persp_exact() {} + + //-------------------------------------------------------------------- + // Arbitrary quadrangle transformations + span_interpolator_persp_exact(const double* src, const double* dst) + { + quad_to_quad(src, dst); + } + + //-------------------------------------------------------------------- + // Direct transformations + span_interpolator_persp_exact(double x1, double y1, + double x2, double y2, + const double* quad) + { + rect_to_quad(x1, y1, x2, y2, quad); + } + + //-------------------------------------------------------------------- + // Reverse transformations + span_interpolator_persp_exact(const double* quad, + double x1, double y1, + double x2, double y2) + { + quad_to_rect(quad, x1, y1, x2, y2); + } + + //-------------------------------------------------------------------- + // Set the transformations using two arbitrary quadrangles. + void quad_to_quad(const double* src, const double* dst) + { + m_trans_dir.quad_to_quad(src, dst); + m_trans_inv.quad_to_quad(dst, src); + } + + //-------------------------------------------------------------------- + // Set the direct transformations, i.e., rectangle -> quadrangle + void rect_to_quad(double x1, double y1, double x2, double y2, + const double* quad) + { + double src[8]; + src[0] = src[6] = x1; + src[2] = src[4] = x2; + src[1] = src[3] = y1; + src[5] = src[7] = y2; + quad_to_quad(src, quad); + } + + + //-------------------------------------------------------------------- + // Set the reverse transformations, i.e., quadrangle -> rectangle + void quad_to_rect(const double* quad, + double x1, double y1, double x2, double y2) + { + double dst[8]; + dst[0] = dst[6] = x1; + dst[2] = dst[4] = x2; + dst[1] = dst[3] = y1; + dst[5] = dst[7] = y2; + quad_to_quad(quad, dst); + } + + //-------------------------------------------------------------------- + // Check if the equations were solved successfully + bool is_valid() const { return m_trans_dir.is_valid(); } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + m_iterator = m_trans_dir.begin(x, y, 1.0); + double xt = m_iterator.x; + double yt = m_iterator.y; + + double dx; + double dy; + const double delta = 1/double(subpixel_scale); + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + x += len; + xt = x; + yt = y; + m_trans_dir.transform(&xt, &yt); + + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + m_scale_x = dda2_line_interpolator(sx1, sx2, len); + m_scale_y = dda2_line_interpolator(sy1, sy2, len); + } + + + //---------------------------------------------------------------- + void resynchronize(double xe, double ye, unsigned len) + { + // Assume x1,y1 are equal to the ones at the previous end point + int sx1 = m_scale_x.y(); + int sy1 = m_scale_y.y(); + + // Calculate transformed coordinates at x2,y2 + double xt = xe; + double yt = ye; + m_trans_dir.transform(&xt, &yt); + + const double delta = 1/double(subpixel_scale); + double dx; + double dy; + + // Calculate scale by X at x2,y2 + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= xe; + dy -= ye; + int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate scale by Y at x2,y2 + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= xe; + dy -= ye; + int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Initialize the interpolators + m_scale_x = dda2_line_interpolator(sx1, sx2, len); + m_scale_y = dda2_line_interpolator(sy1, sy2, len); + } + + + + //---------------------------------------------------------------- + void operator++() + { + ++m_iterator; + ++m_scale_x; + ++m_scale_y; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = iround(m_iterator.x * subpixel_scale); + *y = iround(m_iterator.y * subpixel_scale); + } + + //---------------------------------------------------------------- + void local_scale(int* x, int* y) + { + *x = m_scale_x.y(); + *y = m_scale_y.y(); + } + + //---------------------------------------------------------------- + void transform(double* x, double* y) const + { + m_trans_dir.transform(x, y); + } + + private: + trans_type m_trans_dir; + trans_type m_trans_inv; + iterator_type m_iterator; + dda2_line_interpolator m_scale_x; + dda2_line_interpolator m_scale_y; + }; + + + + + + + + + + + + //============================================span_interpolator_persp_lerp + template + class span_interpolator_persp_lerp + { + public: + typedef trans_perspective trans_type; + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + //-------------------------------------------------------------------- + span_interpolator_persp_lerp() {} + + //-------------------------------------------------------------------- + // Arbitrary quadrangle transformations + span_interpolator_persp_lerp(const double* src, const double* dst) + { + quad_to_quad(src, dst); + } + + //-------------------------------------------------------------------- + // Direct transformations + span_interpolator_persp_lerp(double x1, double y1, + double x2, double y2, + const double* quad) + { + rect_to_quad(x1, y1, x2, y2, quad); + } + + //-------------------------------------------------------------------- + // Reverse transformations + span_interpolator_persp_lerp(const double* quad, + double x1, double y1, + double x2, double y2) + { + quad_to_rect(quad, x1, y1, x2, y2); + } + + //-------------------------------------------------------------------- + // Set the transformations using two arbitrary quadrangles. + void quad_to_quad(const double* src, const double* dst) + { + m_trans_dir.quad_to_quad(src, dst); + m_trans_inv.quad_to_quad(dst, src); + } + + //-------------------------------------------------------------------- + // Set the direct transformations, i.e., rectangle -> quadrangle + void rect_to_quad(double x1, double y1, double x2, double y2, + const double* quad) + { + double src[8]; + src[0] = src[6] = x1; + src[2] = src[4] = x2; + src[1] = src[3] = y1; + src[5] = src[7] = y2; + quad_to_quad(src, quad); + } + + + //-------------------------------------------------------------------- + // Set the reverse transformations, i.e., quadrangle -> rectangle + void quad_to_rect(const double* quad, + double x1, double y1, double x2, double y2) + { + double dst[8]; + dst[0] = dst[6] = x1; + dst[2] = dst[4] = x2; + dst[1] = dst[3] = y1; + dst[5] = dst[7] = y2; + quad_to_quad(quad, dst); + } + + //-------------------------------------------------------------------- + // Check if the equations were solved successfully + bool is_valid() const { return m_trans_dir.is_valid(); } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + // Calculate transformed coordinates at x1,y1 + double xt = x; + double yt = y; + m_trans_dir.transform(&xt, &yt); + int x1 = iround(xt * subpixel_scale); + int y1 = iround(yt * subpixel_scale); + + double dx; + double dy; + const double delta = 1/double(subpixel_scale); + + // Calculate scale by X at x1,y1 + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate scale by Y at x1,y1 + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate transformed coordinates at x2,y2 + x += len; + xt = x; + yt = y; + m_trans_dir.transform(&xt, &yt); + int x2 = iround(xt * subpixel_scale); + int y2 = iround(yt * subpixel_scale); + + // Calculate scale by X at x2,y2 + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate scale by Y at x2,y2 + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Initialize the interpolators + m_coord_x = dda2_line_interpolator(x1, x2, len); + m_coord_y = dda2_line_interpolator(y1, y2, len); + m_scale_x = dda2_line_interpolator(sx1, sx2, len); + m_scale_y = dda2_line_interpolator(sy1, sy2, len); + } + + + //---------------------------------------------------------------- + void resynchronize(double xe, double ye, unsigned len) + { + // Assume x1,y1 are equal to the ones at the previous end point + int x1 = m_coord_x.y(); + int y1 = m_coord_y.y(); + int sx1 = m_scale_x.y(); + int sy1 = m_scale_y.y(); + + // Calculate transformed coordinates at x2,y2 + double xt = xe; + double yt = ye; + m_trans_dir.transform(&xt, &yt); + int x2 = iround(xt * subpixel_scale); + int y2 = iround(yt * subpixel_scale); + + const double delta = 1/double(subpixel_scale); + double dx; + double dy; + + // Calculate scale by X at x2,y2 + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= xe; + dy -= ye; + int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate scale by Y at x2,y2 + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= xe; + dy -= ye; + int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Initialize the interpolators + m_coord_x = dda2_line_interpolator(x1, x2, len); + m_coord_y = dda2_line_interpolator(y1, y2, len); + m_scale_x = dda2_line_interpolator(sx1, sx2, len); + m_scale_y = dda2_line_interpolator(sy1, sy2, len); + } + + + //---------------------------------------------------------------- + void operator++() + { + ++m_coord_x; + ++m_coord_y; + ++m_scale_x; + ++m_scale_y; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = m_coord_x.y(); + *y = m_coord_y.y(); + } + + //---------------------------------------------------------------- + void local_scale(int* x, int* y) + { + *x = m_scale_x.y(); + *y = m_scale_y.y(); + } + + //---------------------------------------------------------------- + void transform(double* x, double* y) const + { + m_trans_dir.transform(x, y); + } + + private: + trans_type m_trans_dir; + trans_type m_trans_inv; + dda2_line_interpolator m_coord_x; + dda2_line_interpolator m_coord_y; + dda2_line_interpolator m_scale_x; + dda2_line_interpolator m_scale_y; + }; + +} + +#endif diff --git a/headers/libs/agg/agg_span_interpolator_trans.h b/headers/libs/agg/agg_span_interpolator_trans.h index 717cc9f0ab..7c474742fe 100644 --- a/headers/libs/agg/agg_span_interpolator_trans.h +++ b/headers/libs/agg/agg_span_interpolator_trans.h @@ -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. @@ -31,11 +31,10 @@ namespace agg { public: typedef Transformer trans_type; - - enum + enum subpixel_scale_e { subpixel_shift = SubpixelShift, - subpixel_size = 1 << subpixel_shift + subpixel_scale = 1 << subpixel_shift }; //-------------------------------------------------------------------- @@ -57,14 +56,20 @@ namespace agg { m_x = x; m_y = y; - transform(); + m_trans->transform(&x, &y); + m_ix = iround(x * subpixel_scale); + m_iy = iround(y * subpixel_scale); } //---------------------------------------------------------------- void operator++() { m_x += 1.0; - transform(); + double x = m_x; + double y = m_y; + m_trans->transform(&x, &y); + m_ix = iround(x * subpixel_scale); + m_iy = iround(y * subpixel_scale); } //---------------------------------------------------------------- @@ -75,16 +80,6 @@ namespace agg } private: - //---------------------------------------------------------------- - void transform() - { - double x = m_x; - double y = m_y; - m_trans->transform(&x, &y); - m_ix = int(x * subpixel_size); - m_iy = int(y * subpixel_size); - } - const trans_type* m_trans; double m_x; double m_y; diff --git a/headers/libs/agg/agg_span_pattern.h b/headers/libs/agg/agg_span_pattern.h deleted file mode 100644 index 3a5b6482d4..0000000000 --- a/headers/libs/agg/agg_span_pattern.h +++ /dev/null @@ -1,78 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - - -#ifndef AGG_SPAN_PATTERN_INCLUDED -#define AGG_SPAN_PATTERN_INCLUDED - -#include "agg_basics.h" -#include "agg_rendering_buffer.h" -#include "agg_span_generator.h" - - -namespace agg -{ - - //--------------------------------------------------------span_pattern - template - class span_pattern : public span_generator - { - public: - typedef ColorT color_type; - typedef AlphaT alpha_type; - typedef Allocator alloc_type; - - //---------------------------------------------------------------- - span_pattern(alloc_type& alloc) : - span_generator(alloc) - {} - - //---------------------------------------------------------------- - span_pattern(alloc_type& alloc, - const rendering_buffer& src, - unsigned offset_x, unsigned offset_y, - alpha_type alpha) : - span_generator(alloc), - m_src(&src), - m_offset_x(offset_x), - m_offset_y(offset_y), - m_alpha(alpha) - {} - - //---------------------------------------------------------------- - const rendering_buffer& source_image() const { return *m_src; } - unsigned offset_x() const { return m_offset_x; } - unsigned offset_y() const { return m_offset_y; } - alpha_type alpha() const { return m_alpha; } - - //---------------------------------------------------------------- - void source_image(const rendering_buffer& v) { m_src = &v; } - void offset_x(unsigned v) { m_offset_x = v; } - void offset_y(unsigned v) { m_offset_y = v; } - void alpha(alpha_type v) { m_alpha = v; } - - //---------------------------------------------------------------- - private: - const rendering_buffer* m_src; - unsigned m_offset_x; - unsigned m_offset_y; - alpha_type m_alpha; - }; - - -} - -#endif - diff --git a/headers/libs/agg/agg_span_pattern_filter_rgba32.h b/headers/libs/agg/agg_span_pattern_filter_rgba32.h deleted file mode 100755 index aea103c862..0000000000 --- a/headers/libs/agg/agg_span_pattern_filter_rgba32.h +++ /dev/null @@ -1,391 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes span_pattern_filter_rgba32* -// -//---------------------------------------------------------------------------- -#ifndef AGG_SPAN_PATTERN_FILTER_RGBA32_INCLUDED -#define AGG_SPAN_PATTERN_FILTER_RGBA32_INCLUDED - -#include "agg_basics.h" -#include "agg_color_rgba8.h" -#include "agg_span_image_filter.h" - - -namespace agg -{ - - //===========================================span_pattern_filter_rgba32_nn - template > - class span_pattern_filter_rgba32_nn : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - - //-------------------------------------------------------------------- - span_pattern_filter_rgba32_nn(alloc_type& alloc) : - base_type(alloc), - m_remainder_x(1), - m_remainder_y(1) - {} - - //-------------------------------------------------------------------- - span_pattern_filter_rgba32_nn(alloc_type& alloc, - const rendering_buffer& src, - interpolator_type& inter) : - base_type(alloc, src, color_type(0,0,0,0), inter, 0), - m_remainder_x(src.width()), - m_remainder_y(src.height()) - {} - - //-------------------------------------------------------------------- - void source_image(const rendering_buffer& src) - { - base_type::source_image(src); - m_remainder_x = RemainderX(src.width()); - m_remainder_y = RemainderX(src.height()); - } - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - const unsigned char *fg_ptr; - color_type* span = base_type::allocator().span(); - do - { - base_type::interpolator().coordinates(&x, &y); - - x = m_remainder_x(x >> image_subpixel_shift); - y = m_remainder_y(y >> image_subpixel_shift); - - fg_ptr = base_type::source_image().row(y) + (x << 2); - span->r = fg_ptr[Order::R]; - span->g = fg_ptr[Order::G]; - span->b = fg_ptr[Order::B]; - span->a = fg_ptr[Order::A]; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - - private: - RemainderX m_remainder_x; - RemainderY m_remainder_y; - }; - - - - - - - - - - - //=====================================span_pattern_filter_rgba32_bilinear - template > - class span_pattern_filter_rgba32_bilinear : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - - //-------------------------------------------------------------------- - span_pattern_filter_rgba32_bilinear(alloc_type& alloc) : - base_type(alloc), - m_remainder_x(1), - m_remainder_y(1) - {} - - //-------------------------------------------------------------------- - span_pattern_filter_rgba32_bilinear(alloc_type& alloc, - const rendering_buffer& src, - interpolator_type& inter) : - base_type(alloc, src, color_type(0,0,0,0), inter, 0), - m_remainder_x(src.width()), - m_remainder_y(src.height()) - {} - - //-------------------------------------------------------------------- - void source_image(const rendering_buffer& src) - { - base_type::source_image(src); - m_remainder_x = RemainderX(src.width()); - m_remainder_y = RemainderX(src.height()); - } - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - int fg[4]; - const int8u *fg_ptr; - color_type* span = base_type::allocator().span(); - - do - { - int x_hr; - int y_hr; - - base_type::interpolator().coordinates(&x_hr, &y_hr); - - x_hr -= base_type::filter_dx_int(); - y_hr -= base_type::filter_dy_int(); - - int x_lr = x_hr >> image_subpixel_shift; - int y_lr = y_hr >> image_subpixel_shift; - - unsigned x1 = m_remainder_x(x_lr); - unsigned x2 = x1 + 1; - if(x2 >= base_type::source_image().width()) x2 = 0; - x1 <<= 2; - x2 <<= 2; - - unsigned y1 = m_remainder_y(y_lr); - unsigned y2 = y1 + 1; - if(y2 >= base_type::source_image().height()) y2 = 0; - const int8u* ptr1 = base_type::source_image().row(y1); - const int8u* ptr2 = base_type::source_image().row(y2); - - fg[0] = - fg[1] = - fg[2] = - fg[3] = image_subpixel_size * image_subpixel_size / 2; - - x_hr &= image_subpixel_mask; - y_hr &= image_subpixel_mask; - - int weight; - fg_ptr = ptr1 + x1; - weight = (image_subpixel_size - x_hr) * - (image_subpixel_size - y_hr); - fg[0] += weight * fg_ptr[0]; - fg[1] += weight * fg_ptr[1]; - fg[2] += weight * fg_ptr[2]; - fg[3] += weight * fg_ptr[3]; - - fg_ptr = ptr1 + x2; - weight = x_hr * (image_subpixel_size - y_hr); - fg[0] += weight * fg_ptr[0]; - fg[1] += weight * fg_ptr[1]; - fg[2] += weight * fg_ptr[2]; - fg[3] += weight * fg_ptr[3]; - - fg_ptr = ptr2 + x1; - weight = (image_subpixel_size - x_hr) * y_hr; - fg[0] += weight * fg_ptr[0]; - fg[1] += weight * fg_ptr[1]; - fg[2] += weight * fg_ptr[2]; - fg[3] += weight * fg_ptr[3]; - - fg_ptr = ptr2 + x2; - weight = x_hr * y_hr; - fg[0] += weight * fg_ptr[0]; - fg[1] += weight * fg_ptr[1]; - fg[2] += weight * fg_ptr[2]; - fg[3] += weight * fg_ptr[3]; - - span->r = (int8u)(fg[Order::R] >> image_subpixel_shift * 2); - span->g = (int8u)(fg[Order::G] >> image_subpixel_shift * 2); - span->b = (int8u)(fg[Order::B] >> image_subpixel_shift * 2); - span->a = (int8u)(fg[Order::A] >> image_subpixel_shift * 2); - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - private: - RemainderX m_remainder_x; - RemainderY m_remainder_y; - }; - - - - - - //==============================================span_pattern_filter_rgba32 - template > - class span_pattern_filter_rgba32 : - public span_image_filter - { - public: - typedef Interpolator interpolator_type; - typedef Allocator alloc_type; - typedef span_image_filter base_type; - typedef rgba8 color_type; - - //-------------------------------------------------------------------- - span_pattern_filter_rgba32(alloc_type& alloc) : - base_type(alloc) - {} - - //-------------------------------------------------------------------- - span_pattern_filter_rgba32(alloc_type& alloc, - const rendering_buffer& src, - interpolator_type& inter, - const image_filter_base& filter) : - base_type(alloc, src, color_type(0,0,0,0), inter, &filter), - m_remainder_x(src.width()), - m_remainder_y(src.height()) - {} - - //-------------------------------------------------------------------- - void source_image(const rendering_buffer& src) - { - base_type::source_image(src); - m_remainder_x = RemainderX(src.width()); - m_remainder_y = RemainderX(src.height()); - } - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - base_type::interpolator().begin(x + base_type::filter_dx_dbl(), - y + base_type::filter_dy_dbl(), len); - int fg[4]; - - const unsigned char *fg_ptr; - - unsigned dimension = base_type::filter().dimension(); - int start = base_type::filter().start(); - const int* weight_array = base_type::filter().weight_array_int(); - - color_type* span = base_type::allocator().span(); - - int x_count; - int weight_y; - - do - { - base_type::interpolator().coordinates(&x, &y); - - x -= base_type::filter_dx_int(); - y -= base_type::filter_dy_int(); - - int x_hr = x; - int y_hr = y; - - int x_fract = x_hr & image_subpixel_mask; - unsigned y_count = dimension; - - int y_lr = m_remainder_y((y >> image_subpixel_shift) + start); - int x_int = m_remainder_x((x >> image_subpixel_shift) + start); - int x_lr; - - y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); - fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2; - - do - { - x_count = dimension; - weight_y = weight_array[y_hr]; - x_hr = image_subpixel_mask - x_fract; - x_lr = x_int; - fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); - - do - { - int weight = (weight_y * weight_array[x_hr] + - image_filter_size / 2) >> - image_filter_shift; - - fg[0] += *fg_ptr++ * weight; - fg[1] += *fg_ptr++ * weight; - fg[2] += *fg_ptr++ * weight; - fg[3] += *fg_ptr++ * weight; - - x_hr += image_subpixel_size; - ++x_lr; - if(x_lr >= int(base_type::source_image().width())) - { - x_lr = 0; - fg_ptr = base_type::source_image().row(y_lr); - } - - } while(--x_count); - - y_hr += image_subpixel_size; - ++y_lr; - if(y_lr >= int(base_type::source_image().height())) y_lr = 0; - - } while(--y_count); - - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; - fg[3] >>= image_filter_shift; - - if(fg[0] < 0) fg[0] = 0; - if(fg[1] < 0) fg[1] = 0; - if(fg[2] < 0) fg[2] = 0; - if(fg[3] < 0) fg[3] = 0; - - if(fg[Order::A] > 255) fg[Order::A] = 255; - if(fg[Order::R] > fg[Order::A]) fg[Order::R] = fg[Order::A]; - if(fg[Order::G] > fg[Order::A]) fg[Order::G] = fg[Order::A]; - if(fg[Order::B] > fg[Order::A]) fg[Order::B] = fg[Order::A]; - - span->r = fg[Order::R]; - span->g = fg[Order::G]; - span->b = fg[Order::B]; - span->a = fg[Order::A]; - ++span; - ++base_type::interpolator(); - - } while(--len); - - return base_type::allocator().span(); - } - - private: - RemainderX m_remainder_x; - RemainderY m_remainder_y; - }; - - -} - - -#endif - - - diff --git a/headers/libs/agg/agg_span_pattern_gray.h b/headers/libs/agg/agg_span_pattern_gray.h new file mode 100644 index 0000000000..ae1a49f879 --- /dev/null +++ b/headers/libs/agg/agg_span_pattern_gray.h @@ -0,0 +1,93 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_SPAN_PATTERN_GRAY_INCLUDED +#define AGG_SPAN_PATTERN_GRAY_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //=======================================================span_pattern_gray + template class span_pattern_gray + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + + //-------------------------------------------------------------------- + span_pattern_gray() {} + span_pattern_gray(source_type& src, + unsigned offset_x, unsigned offset_y) : + m_src(&src), + m_offset_x(offset_x), + m_offset_y(offset_y), + m_alpha(color_type::base_mask) + {} + + //-------------------------------------------------------------------- + void attach(source_type& v) { m_src = &v; } + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + + //-------------------------------------------------------------------- + void offset_x(unsigned v) { m_offset_x = v; } + void offset_y(unsigned v) { m_offset_y = v; } + unsigned offset_x() const { return m_offset_x; } + unsigned offset_y() const { return m_offset_y; } + void alpha(value_type v) { m_alpha = v; } + value_type alpha() const { return m_alpha; } + + //-------------------------------------------------------------------- + void prepare() {} + void generate(color_type* span, int x, int y, unsigned len) + { + x += m_offset_x; + y += m_offset_y; + const value_type* p = (const value_type*)m_src->span(x, y, len); + do + { + span->v = *p; + span->a = m_alpha; + p = m_src->next_x(); + ++span; + } + while(--len); + } + + private: + source_type* m_src; + unsigned m_offset_x; + unsigned m_offset_y; + value_type m_alpha; + + }; + +} + +#endif + diff --git a/headers/libs/agg/agg_span_pattern_rgb.h b/headers/libs/agg/agg_span_pattern_rgb.h new file mode 100644 index 0000000000..4850508af1 --- /dev/null +++ b/headers/libs/agg/agg_span_pattern_rgb.h @@ -0,0 +1,96 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_SPAN_PATTERN_RGB_INCLUDED +#define AGG_SPAN_PATTERN_RGB_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //========================================================span_pattern_rgb + template class span_pattern_rgb + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + + //-------------------------------------------------------------------- + span_pattern_rgb() {} + span_pattern_rgb(source_type& src, + unsigned offset_x, unsigned offset_y) : + m_src(&src), + m_offset_x(offset_x), + m_offset_y(offset_y), + m_alpha(color_type::base_mask) + {} + + //-------------------------------------------------------------------- + void attach(source_type& v) { m_src = &v; } + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + + //-------------------------------------------------------------------- + void offset_x(unsigned v) { m_offset_x = v; } + void offset_y(unsigned v) { m_offset_y = v; } + unsigned offset_x() const { return m_offset_x; } + unsigned offset_y() const { return m_offset_y; } + void alpha(value_type v) { m_alpha = v; } + value_type alpha() const { return m_alpha; } + + //-------------------------------------------------------------------- + void prepare() {} + void generate(color_type* span, int x, int y, unsigned len) + { + x += m_offset_x; + y += m_offset_y; + const value_type* p = (const value_type*)m_src->span(x, y, len); + do + { + span->r = p[order_type::R]; + span->g = p[order_type::G]; + span->b = p[order_type::B]; + span->a = m_alpha; + p = m_src->next_x(); + ++span; + } + while(--len); + } + + private: + source_type* m_src; + unsigned m_offset_x; + unsigned m_offset_y; + value_type m_alpha; + + }; + +} + +#endif + diff --git a/headers/libs/agg/agg_span_pattern_rgb24.h b/headers/libs/agg/agg_span_pattern_rgb24.h deleted file mode 100644 index 88da15030f..0000000000 --- a/headers/libs/agg/agg_span_pattern_rgb24.h +++ /dev/null @@ -1,79 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - - -#ifndef AGG_SPAN_PATTERN_RGB24_INCLUDED -#define AGG_SPAN_PATTERN_RGB24_INCLUDED - -#include "agg_basics.h" -#include "agg_pixfmt_rgb24.h" -#include "agg_span_pattern.h" - -namespace agg -{ - - //=======================================================span_pattern_rgb24 - template > - class span_pattern_rgb24 : public span_pattern - { - public: - typedef Allocator alloc_type; - typedef rgba8 color_type; - typedef span_pattern base_type; - - //-------------------------------------------------------------------- - span_pattern_rgb24(alloc_type& alloc) : base_type(alloc) {} - - //---------------------------------------------------------------- - span_pattern_rgb24(alloc_type& alloc, - const rendering_buffer& src, - unsigned offset_x, unsigned offset_y, - int8u alpha = 255) : - base_type(alloc, src, offset_x, offset_y, alpha) - {} - - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - color_type* span = base_type::allocator().span(); - unsigned sx = (base_type::offset_x() + x) % base_type::source_image().width(); - unsigned wp = base_type::source_image().width() * 3; - const int8u* p = base_type::source_image().row((base_type::offset_y() + y) % base_type::source_image().height()); - p += sx * 3; - do - { - span->r = p[Order::R]; - span->g = p[Order::G]; - span->b = p[Order::B]; - span->a = base_type::alpha(); - p += 3; - ++sx; - ++span; - if(sx >= base_type::source_image().width()) - { - sx -= base_type::source_image().width(); - p -= wp; - } - } - while(--len); - return base_type::allocator().span(); - } - }; - -} - -#endif - diff --git a/headers/libs/agg/agg_span_pattern_rgba.h b/headers/libs/agg/agg_span_pattern_rgba.h new file mode 100644 index 0000000000..d47d2a6c02 --- /dev/null +++ b/headers/libs/agg/agg_span_pattern_rgba.h @@ -0,0 +1,94 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// 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_SPAN_PATTERN_RGBA_INCLUDED +#define AGG_SPAN_PATTERN_RGBA_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //======================================================span_pattern_rgba + template class span_pattern_rgba + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + + //-------------------------------------------------------------------- + span_pattern_rgba() {} + span_pattern_rgba(source_type& src, + unsigned offset_x, unsigned offset_y) : + m_src(&src), + m_offset_x(offset_x), + m_offset_y(offset_y) + {} + + //-------------------------------------------------------------------- + void attach(source_type& v) { m_src = &v; } + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + + //-------------------------------------------------------------------- + void offset_x(unsigned v) { m_offset_x = v; } + void offset_y(unsigned v) { m_offset_y = v; } + unsigned offset_x() const { return m_offset_x; } + unsigned offset_y() const { return m_offset_y; } + void alpha(value_type) {} + value_type alpha() const { return 0; } + + //-------------------------------------------------------------------- + void prepare() {} + void generate(color_type* span, int x, int y, unsigned len) + { + x += m_offset_x; + y += m_offset_y; + const value_type* p = (const value_type*)m_src->span(x, y, len); + do + { + span->r = p[order_type::R]; + span->g = p[order_type::G]; + span->b = p[order_type::B]; + span->a = p[order_type::A]; + p = (const value_type*)m_src->next_x(); + ++span; + } + while(--len); + } + + private: + source_type* m_src; + unsigned m_offset_x; + unsigned m_offset_y; + + }; + +} + +#endif + diff --git a/headers/libs/agg/agg_span_pattern_rgba32.h b/headers/libs/agg/agg_span_pattern_rgba32.h deleted file mode 100644 index 5b9cea7906..0000000000 --- a/headers/libs/agg/agg_span_pattern_rgba32.h +++ /dev/null @@ -1,77 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - - -#ifndef AGG_SPAN_PATTERN_RGBA32_INCLUDED -#define AGG_SPAN_PATTERN_RGBA32_INCLUDED - -#include "agg_basics.h" -#include "agg_pixfmt_rgba32.h" -#include "agg_span_pattern.h" - -namespace agg -{ - - //======================================================span_pattern_rgba32 - template > - class span_pattern_rgba32 : public span_pattern - { - public: - typedef Allocator alloc_type; - typedef rgba8 color_type; - typedef span_pattern base_type; - - //-------------------------------------------------------------------- - span_pattern_rgba32(alloc_type& alloc) : base_type(alloc) {} - - //---------------------------------------------------------------- - span_pattern_rgba32(alloc_type& alloc, - const rendering_buffer& src, - unsigned offset_x, unsigned offset_y) : - base_type(alloc, src, offset_x, offset_y, 0) - {} - - //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) - { - color_type* span = base_type::allocator().span(); - unsigned sx = (base_type::offset_x() + x) % base_type::source_image().width(); - unsigned wp = base_type::source_image().width() << 2; - const int8u* p = base_type::source_image().row((base_type::offset_y() + y) % base_type::source_image().height()); - p += sx << 2; - do - { - span->r = p[Order::R]; - span->g = p[Order::G]; - span->b = p[Order::B]; - span->a = p[Order::A]; - p += 4; - ++sx; - ++span; - if(sx >= base_type::source_image().width()) - { - sx -= base_type::source_image().width(); - p -= wp; - } - } - while(--len); - return base_type::allocator().span(); - } - }; - -} - -#endif - diff --git a/headers/libs/agg/agg_span_solid.h b/headers/libs/agg/agg_span_solid.h index fe84bd791e..ee46df9991 100644 --- a/headers/libs/agg/agg_span_solid.h +++ b/headers/libs/agg/agg_span_solid.h @@ -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,36 +21,26 @@ #define AGG_SPAN_SOLID_INCLUDED #include "agg_basics.h" -#include "agg_span_generator.h" namespace agg { //--------------------------------------------------------------span_solid - template > - class span_solid : public span_generator + template class span_solid { public: - typedef Allocator alloc_type; typedef ColorT color_type; - typedef span_generator base_type; - - //-------------------------------------------------------------------- - span_solid(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- void color(const color_type& c) { m_color = c; } const color_type& color() const { return m_color; } //-------------------------------------------------------------------- - color_type* generate(int x, int y, unsigned len) + void prepare() {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) { - color_type* span = base_type::allocator().span(); - do - { - *span++ = m_color; - } - while(--len); - return base_type::allocator().span(); + do { *span++ = m_color; } while(--len); } private: diff --git a/headers/libs/agg/agg_span_subdiv_adaptor.h b/headers/libs/agg/agg_span_subdiv_adaptor.h new file mode 100644 index 0000000000..b5b855ec97 --- /dev/null +++ b/headers/libs/agg/agg_span_subdiv_adaptor.h @@ -0,0 +1,141 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_SUBDIV_ADAPTOR_INCLUDED +#define AGG_SPAN_SUBDIV_ADAPTOR_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //=================================================span_subdiv_adaptor + template + class span_subdiv_adaptor + { + public: + typedef Interpolator interpolator_type; + typedef typename interpolator_type::trans_type trans_type; + + enum sublixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + + //---------------------------------------------------------------- + span_subdiv_adaptor() : + m_subdiv_shift(4), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1) {} + + span_subdiv_adaptor(interpolator_type& interpolator, + unsigned subdiv_shift = 4) : + m_subdiv_shift(subdiv_shift), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1), + m_interpolator(&interpolator) {} + + span_subdiv_adaptor(interpolator_type& interpolator, + double x, double y, unsigned len, + unsigned subdiv_shift = 4) : + m_subdiv_shift(subdiv_shift), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1), + m_interpolator(&interpolator) + { + begin(x, y, len); + } + + + //---------------------------------------------------------------- + const interpolator_type& interpolator() const { return *m_interpolator; } + void interpolator(interpolator_type& intr) { m_interpolator = &intr; } + + //---------------------------------------------------------------- + const trans_type& transformer() const + { + return *m_interpolator->transformer(); + } + void transformer(const trans_type& trans) + { + m_interpolator->transformer(trans); + } + + //---------------------------------------------------------------- + unsigned subdiv_shift() const { return m_subdiv_shift; } + void subdiv_shift(unsigned shift) + { + m_subdiv_shift = shift; + m_subdiv_size = 1 << m_subdiv_shift; + m_subdiv_mask = m_subdiv_size - 1; + } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + m_pos = 1; + m_src_x = iround(x * subpixel_scale) + subpixel_scale; + m_src_y = y; + m_len = len; + if(len > m_subdiv_size) len = m_subdiv_size; + m_interpolator->begin(x, y, len); + } + + //---------------------------------------------------------------- + void operator++() + { + ++(*m_interpolator); + if(m_pos >= m_subdiv_size) + { + unsigned len = m_len; + if(len > m_subdiv_size) len = m_subdiv_size; + m_interpolator->resynchronize(double(m_src_x) / double(subpixel_scale) + len, + m_src_y, + len); + m_pos = 0; + } + m_src_x += subpixel_scale; + ++m_pos; + --m_len; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + m_interpolator->coordinates(x, y); + } + + //---------------------------------------------------------------- + void local_scale(int* x, int* y) const + { + m_interpolator->local_scale(x, y); + } + + + private: + unsigned m_subdiv_shift; + unsigned m_subdiv_size; + unsigned m_subdiv_mask; + interpolator_type* m_interpolator; + int m_src_x; + double m_src_y; + unsigned m_pos; + unsigned m_len; + }; + +} + +#endif diff --git a/headers/libs/agg/agg_trans_affine.h b/headers/libs/agg/agg_trans_affine.h index 5965009715..0f9b21e36f 100755 --- a/headers/libs/agg/agg_trans_affine.h +++ b/headers/libs/agg/agg_trans_affine.h @@ -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. @@ -148,6 +148,12 @@ namespace agg // Multiply "m" to "this" and assign the result to "this" const trans_affine& premultiply(const trans_affine& m); + // Multiply matrix to inverse of another one + const trans_affine& multiply_inv(const trans_affine& m); + + // Multiply inverse of "m" to "this" and assign the result to "this" + const trans_affine& premultiply_inv(const trans_affine& m); + // Invert matrix. Do not try to invert degenerate matrices, // there's no check for validity. If you set scale to 0 and // then try to invert matrix, expect unpredictable result. @@ -181,6 +187,12 @@ namespace agg return multiply(m); } + // Multiply current matrix to inverse of another one + const trans_affine& operator /= (const trans_affine& m) + { + return multiply_inv(m); + } + // Multiply current matrix to another one and return // the result in a separete matrix. trans_affine operator * (const trans_affine& m) @@ -188,6 +200,13 @@ namespace agg return trans_affine(*this).multiply(m); } + // Multiply current matrix to inverse of another one + // and return the result in a separete matrix. + trans_affine operator / (const trans_affine& m) + { + return trans_affine(*this).multiply_inv(m); + } + // Calculate and return the inverse matrix trans_affine operator ~ () const { @@ -211,6 +230,9 @@ namespace agg // Direct transformation x and y void transform(double* x, double* y) const; + // Direct transformation x and y, 2x2 matrix only, no translation + void transform_2x2(double* x, double* y) const; + // Inverse transformation x and y. It works slower than the // direct transformation, so if the performance is critical // it's better to invert() the matrix and then use transform() @@ -238,6 +260,11 @@ namespace agg double rotation() const; void translation(double* dx, double* dy) const; void scaling(double* sx, double* sy) const; + void scaling_abs(double* sx, double* sy) const + { + *sx = sqrt(m0*m0 + m2*m2); + *sy = sqrt(m1*m1 + m3*m3); + } private: double m0; @@ -256,6 +283,14 @@ namespace agg *y = tx * m1 + *y * m3 + m5; } + //------------------------------------------------------------------------ + inline void trans_affine::transform_2x2(double* x, double* y) const + { + register double tx = *x; + *x = tx * m0 + *y * m2; + *y = tx * m1 + *y * m3; + } + //------------------------------------------------------------------------ inline void trans_affine::inverse_transform(double* x, double* y) const { @@ -274,7 +309,6 @@ namespace agg return sqrt(x*x + y*y); } - //------------------------------------------------------------------------ inline const trans_affine& trans_affine::premultiply(const trans_affine& m) { @@ -282,6 +316,22 @@ namespace agg return *this = t.multiply(*this); } + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::multiply_inv(const trans_affine& m) + { + trans_affine t = m; + t.invert(); + multiply(t); + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::premultiply_inv(const trans_affine& m) + { + trans_affine t = m; + t.invert(); + return *this = t.multiply(*this); + } //====================================================trans_affine_rotation // Rotation matrix. sin() and cos() are calculated twice for the same angle. @@ -331,6 +381,26 @@ namespace agg }; + //===============================================trans_affine_line_segment + // Rotate, Scale and Translate, associating 0...dist with line segment + // x1,y1,x2,y2 + class trans_affine_line_segment : public trans_affine + { + public: + trans_affine_line_segment(double x1, double y1, double x2, double y2, + double dist) + { + double dx = x2 - x1; + double dy = y2 - y1; + if(dist > 0.0) + { + multiply(trans_affine_scaling(sqrt(dx * dx + dy * dy) / dist)); + } + multiply(trans_affine_rotation(atan2(dy, dx))); + multiply(trans_affine_translation(x1, y1)); + } + }; + } diff --git a/headers/libs/agg/agg_trans_bilinear.h b/headers/libs/agg/agg_trans_bilinear.h index ea66819c27..f3ab596472 100644 --- a/headers/libs/agg/agg_trans_bilinear.h +++ b/headers/libs/agg/agg_trans_bilinear.h @@ -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. @@ -124,6 +124,38 @@ namespace agg *y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty; } + + //-------------------------------------------------------------------- + class iterator_x + { + double inc_x; + double inc_y; + + public: + double x; + double y; + + iterator_x() {} + iterator_x(double tx, double ty, double step, const double m[4][2]) : + inc_x(m[1][0] * step * ty + m[2][0] * step), + inc_y(m[1][1] * step * ty + m[2][1] * step), + x(m[0][0] + m[1][0] * tx * ty + m[2][0] * tx + m[3][0] * ty), + y(m[0][1] + m[1][1] * tx * ty + m[2][1] * tx + m[3][1] * ty) + { + } + + void operator ++ () + { + x += inc_x; + y += inc_y; + } + }; + + iterator_x begin(double x, double y, double step) const + { + return iterator_x(x, y, step, m_mtx); + } + private: double m_mtx[4][2]; bool m_valid; diff --git a/headers/libs/agg/agg_trans_double_path.h b/headers/libs/agg/agg_trans_double_path.h index 52569e6ac0..c645a7f869 100755 --- a/headers/libs/agg/agg_trans_double_path.h +++ b/headers/libs/agg/agg_trans_double_path.h @@ -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. diff --git a/headers/libs/agg/agg_trans_lens.h b/headers/libs/agg/agg_trans_lens.h new file mode 100644 index 0000000000..dfcdaf9a8f --- /dev/null +++ b/headers/libs/agg/agg_trans_lens.h @@ -0,0 +1,79 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.1 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- + +#ifndef AGG_WARP_MAGNIFIER_INCLUDED +#define AGG_WARP_MAGNIFIER_INCLUDED + +#include +#include "agg_basics.h" + + +namespace agg +{ + + class trans_warp_magnifier + { + public: + trans_warp_magnifier() : m_xc(0.0), m_yc(0.0), m_magn(1.0), m_radius(1.0), m_warp(false) {} + + void center(double x, double y) { m_xc = x; m_yc = y; } + void magnification(double m) { m_magn = m; } + void radius(double r) { m_radius = r; } + void warp(bool w) { m_warp = w; } + + void transform(double* x, double* y) const + { + double dx = *x - m_xc; + double dy = *y - m_yc; + double r = sqrt(dx * dx + dy * dy); + double rm = m_radius / m_magn; + if(r < rm) + { + *x = m_xc + dx * m_magn; + *y = m_yc + dy * m_magn; + return; + } + + if(m_warp) + { + double m = (r + rm * (m_magn - 1.0)) / r; + *x = m_xc + dx * m; + *y = m_yc + dy * m; + return; + } + + if(r < m_radius) + { + double m = m_radius / r; + *x = m_xc + dx * m; + *y = m_yc + dy * m; + } + } + + private: + double m_xc; + double m_yc; + double m_magn; + double m_radius; + bool m_warp; + }; + + + +} + + +#endif + diff --git a/headers/libs/agg/agg_trans_perspective.h b/headers/libs/agg/agg_trans_perspective.h index 3a46de5e47..0937494a19 100644 --- a/headers/libs/agg/agg_trans_perspective.h +++ b/headers/libs/agg/agg_trans_perspective.h @@ -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. @@ -138,6 +138,50 @@ namespace agg *y = (m_mtx[3][0] + m_mtx[4][0] * tx + m_mtx[5][0] * ty) * d; } + //-------------------------------------------------------------------- + class iterator_x + { + double den; + double den_step; + double nom_x; + double nom_x_step; + double nom_y; + double nom_y_step; + + public: + double x; + double y; + + iterator_x() {} + iterator_x(double tx, double ty, double step, const double m[8][1]) : + den(m[6][0] * tx + m[7][0] * ty + 1.0), + den_step(m[6][0] * step), + nom_x(m[0][0] + m[1][0] * tx + m[2][0] * ty), + nom_x_step(m[1][0] * step), + nom_y(m[3][0] + m[4][0] * tx + m[5][0] * ty), + nom_y_step(m[4][0] * step), + x(nom_x / den), + y(nom_y / den) + { + } + + void operator ++ () + { + den += den_step; + nom_x += nom_x_step; + nom_y += nom_y_step; + double d = 1.0 / den; + x = nom_x * d; + y = nom_y * d; + } + }; + + //-------------------------------------------------------------------- + iterator_x begin(double x, double y, double step) const + { + return iterator_x(x, y, step, m_mtx); + } + private: double m_mtx[8][1]; bool m_valid; diff --git a/headers/libs/agg/agg_trans_single_path.h b/headers/libs/agg/agg_trans_single_path.h index ef333d19f5..9f4bf53bdb 100755 --- a/headers/libs/agg/agg_trans_single_path.h +++ b/headers/libs/agg/agg_trans_single_path.h @@ -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. diff --git a/headers/libs/agg/agg_trans_viewport.h b/headers/libs/agg/agg_trans_viewport.h index 4817dec109..7088f99078 100755 --- a/headers/libs/agg/agg_trans_viewport.h +++ b/headers/libs/agg/agg_trans_viewport.h @@ -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,7 +22,7 @@ #define AGG_TRANS_VIEWPORT_INCLUDED #include -#include "agg_basics.h" +#include "agg_trans_affine.h" namespace agg @@ -51,6 +51,7 @@ namespace agg m_device_x2(1.0), m_device_y2(1.0), m_aspect(aspect_ratio_stretch), + m_is_valid(true), m_align_x(0.5), m_align_y(0.5), m_wx1(0.0), @@ -123,6 +124,7 @@ namespace agg } //------------------------------------------------------------------- + bool is_valid() const { return m_is_valid; } double align_x() const { return m_align_x; } double align_y() const { return m_align_y; } aspect_ratio_e aspect_ratio() const { return m_aspect; } @@ -134,6 +136,13 @@ namespace agg *y = (*y - m_wy1) * m_ky + m_dy1; } + //------------------------------------------------------------------- + void transform_scale_only(double* x, double* y) const + { + *x *= m_kx; + *y *= m_ky; + } + //------------------------------------------------------------------- void inverse_transform(double* x, double* y) const { @@ -141,6 +150,17 @@ namespace agg *y = (*y - m_dy1) / m_ky + m_wy1; } + //------------------------------------------------------------------- + void inverse_transform_scale_only(double* x, double* y) const + { + *x /= m_kx; + *y /= m_ky; + } + + //------------------------------------------------------------------- + double device_dx() const { return m_dx1 - m_wx1 * m_kx; } + double device_dy() const { return m_dy1 - m_wy1 * m_ky; } + //------------------------------------------------------------------- double scale_x() const { @@ -159,76 +179,35 @@ namespace agg return (m_kx + m_ky) * 0.5; } + //------------------------------------------------------------------- + trans_affine to_affine() const + { + trans_affine mtx = trans_affine_translation(-m_wx1, -m_wy1); + mtx *= trans_affine_scaling(m_kx, m_ky); + mtx *= trans_affine_translation(m_dx1, m_dy1); + return mtx; + } + + //------------------------------------------------------------------- + trans_affine to_affine_scale_only() const + { + return trans_affine_scaling(m_kx, m_ky); + } //------------------------------------------------------------------- unsigned byte_size() const { - return - sizeof(m_world_x1) + - sizeof(m_world_y1) + - sizeof(m_world_x2) + - sizeof(m_world_y2) + - sizeof(m_device_x1) + - sizeof(m_device_y1) + - sizeof(m_device_x2) + - sizeof(m_device_y2) + - sizeof(m_aspect) + - sizeof(m_align_x) + - sizeof(m_align_y) + - sizeof(m_wx1) + - sizeof(m_wy1) + - sizeof(m_wx2) + - sizeof(m_wy2) + - sizeof(m_dx1) + - sizeof(m_dy1) + - sizeof(m_kx) + - sizeof(m_ky); + return sizeof(*this); } void serialize(int8u* ptr) const { - memcpy(ptr, &m_world_x1, sizeof(m_world_x1)); ptr += sizeof(m_world_x1); - memcpy(ptr, &m_world_y1, sizeof(m_world_y1)); ptr += sizeof(m_world_y1); - memcpy(ptr, &m_world_x2, sizeof(m_world_x2)); ptr += sizeof(m_world_x2); - memcpy(ptr, &m_world_y2, sizeof(m_world_y2)); ptr += sizeof(m_world_y2); - memcpy(ptr, &m_device_x1, sizeof(m_device_x1)); ptr += sizeof(m_device_x1); - memcpy(ptr, &m_device_y1, sizeof(m_device_y1)); ptr += sizeof(m_device_y1); - memcpy(ptr, &m_device_x2, sizeof(m_device_x2)); ptr += sizeof(m_device_x2); - memcpy(ptr, &m_device_y2, sizeof(m_device_y2)); ptr += sizeof(m_device_y2); - memcpy(ptr, &m_aspect, sizeof(m_aspect)); ptr += sizeof(m_aspect); - memcpy(ptr, &m_align_x, sizeof(m_align_x)); ptr += sizeof(m_align_x); - memcpy(ptr, &m_align_y, sizeof(m_align_y)); ptr += sizeof(m_align_y); - memcpy(ptr, &m_wx1, sizeof(m_wx1)); ptr += sizeof(m_wx1); - memcpy(ptr, &m_wy1, sizeof(m_wy1)); ptr += sizeof(m_wy1); - memcpy(ptr, &m_wx2, sizeof(m_wx2)); ptr += sizeof(m_wx2); - memcpy(ptr, &m_wy2, sizeof(m_wy2)); ptr += sizeof(m_wy2); - memcpy(ptr, &m_dx1, sizeof(m_dx1)); ptr += sizeof(m_dx1); - memcpy(ptr, &m_dy1, sizeof(m_dy1)); ptr += sizeof(m_dy1); - memcpy(ptr, &m_kx, sizeof(m_kx)); ptr += sizeof(m_kx); - memcpy(ptr, &m_ky, sizeof(m_ky)); ptr += sizeof(m_ky); + memcpy(ptr, this, sizeof(*this)); } void deserialize(const int8u* ptr) { - memcpy(&m_world_x1, ptr, sizeof(m_world_x1)); ptr += sizeof(m_world_x1); - memcpy(&m_world_y1, ptr, sizeof(m_world_y1)); ptr += sizeof(m_world_y1); - memcpy(&m_world_x2, ptr, sizeof(m_world_x2)); ptr += sizeof(m_world_x2); - memcpy(&m_world_y2, ptr, sizeof(m_world_y2)); ptr += sizeof(m_world_y2); - memcpy(&m_device_x1, ptr, sizeof(m_device_x1)); ptr += sizeof(m_device_x1); - memcpy(&m_device_y1, ptr, sizeof(m_device_y1)); ptr += sizeof(m_device_y1); - memcpy(&m_device_x2, ptr, sizeof(m_device_x2)); ptr += sizeof(m_device_x2); - memcpy(&m_device_y2, ptr, sizeof(m_device_y2)); ptr += sizeof(m_device_y2); - memcpy(&m_aspect, ptr, sizeof(m_aspect)); ptr += sizeof(m_aspect); - memcpy(&m_align_x, ptr, sizeof(m_align_x)); ptr += sizeof(m_align_x); - memcpy(&m_align_y, ptr, sizeof(m_align_y)); ptr += sizeof(m_align_y); - memcpy(&m_wx1, ptr, sizeof(m_wx1)); ptr += sizeof(m_wx1); - memcpy(&m_wy1, ptr, sizeof(m_wy1)); ptr += sizeof(m_wy1); - memcpy(&m_wx2, ptr, sizeof(m_wx2)); ptr += sizeof(m_wx2); - memcpy(&m_wy2, ptr, sizeof(m_wy2)); ptr += sizeof(m_wy2); - memcpy(&m_dx1, ptr, sizeof(m_dx1)); ptr += sizeof(m_dx1); - memcpy(&m_dy1, ptr, sizeof(m_dy1)); ptr += sizeof(m_dy1); - memcpy(&m_kx, ptr, sizeof(m_kx)); ptr += sizeof(m_kx); - memcpy(&m_ky, ptr, sizeof(m_ky)); ptr += sizeof(m_ky); + memcpy(this, ptr, sizeof(*this)); } private: @@ -243,6 +222,7 @@ namespace agg double m_device_x2; double m_device_y2; aspect_ratio_e m_aspect; + bool m_is_valid; double m_align_x; double m_align_y; double m_wx1; @@ -260,6 +240,24 @@ namespace agg //----------------------------------------------------------------------- inline void trans_viewport::update() { + const double epsilon = 1e-30; + if(fabs(m_world_x1 - m_world_x2) < epsilon || + fabs(m_world_y1 - m_world_y2) < epsilon || + fabs(m_device_x1 - m_device_x2) < epsilon || + fabs(m_device_y1 - m_device_y2) < epsilon) + { + m_wx1 = m_world_x1; + m_wy1 = m_world_y1; + m_wx2 = m_world_x1 + 1.0; + m_wy2 = m_world_y2 + 1.0; + m_dx1 = m_device_x1; + m_dy1 = m_device_y1; + m_kx = 1.0; + m_ky = 1.0; + m_is_valid = false; + return; + } + double world_x1 = m_world_x1; double world_y1 = m_world_y1; double world_x2 = m_world_x2; @@ -295,6 +293,7 @@ namespace agg m_dy1 = device_y1; m_kx = (device_x2 - device_x1) / (world_x2 - world_x1); m_ky = (device_y2 - device_y1) / (world_y2 - world_y1); + m_is_valid = true; } diff --git a/headers/libs/agg/agg_trans_warp_magnifier.h b/headers/libs/agg/agg_trans_warp_magnifier.h index 45f582a885..fe8de000f5 100755 --- a/headers/libs/agg/agg_trans_warp_magnifier.h +++ b/headers/libs/agg/agg_trans_warp_magnifier.h @@ -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. diff --git a/headers/libs/agg/agg_vcgen_bspline.h b/headers/libs/agg/agg_vcgen_bspline.h index d45425b6c9..a2944548c0 100644 --- a/headers/libs/agg/agg_vcgen_bspline.h +++ b/headers/libs/agg/agg_vcgen_bspline.h @@ -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. @@ -37,7 +37,7 @@ namespace agg }; public: - typedef pod_deque vertex_storage; + typedef pod_bvector vertex_storage; vcgen_bspline(); @@ -49,7 +49,7 @@ namespace agg void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface - void rewind(unsigned id); + void rewind(unsigned path_id); unsigned vertex(double* x, double* y); private: diff --git a/headers/libs/agg/agg_vcgen_contour.h b/headers/libs/agg/agg_vcgen_contour.h index 2e79d01905..8c25da13f5 100755 --- a/headers/libs/agg/agg_vcgen_contour.h +++ b/headers/libs/agg/agg_vcgen_contour.h @@ -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_VCGEN_CONTOUR_INCLUDED #include "agg_math_stroke.h" -#include "agg_vertex_iterator.h" namespace agg { @@ -40,55 +39,54 @@ namespace agg public: typedef vertex_sequence vertex_storage; - typedef pod_deque coord_storage; + typedef pod_bvector coord_storage; vcgen_contour(); - void line_join(line_join_e lj) { m_line_join = lj; } - void inner_line_join(line_join_e lj) { m_inner_line_join = lj; } - void width(double w) { m_width = w * 0.5; } - 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; } - void auto_detect_orientation(bool v) { m_auto_detect = v; } + void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); } + void line_join(line_join_e lj) { m_stroker.line_join(lj); } + void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); } - line_join_e line_join() const { return m_line_join; } - line_join_e inner_line_join() const { return m_inner_line_join; } - 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; } - bool auto_detect_orientation() const { return m_auto_detect; } + line_cap_e line_cap() const { return m_stroker.line_cap(); } + line_join_e line_join() const { return m_stroker.line_join(); } + inner_join_e inner_join() const { return m_stroker.inner_join(); } + + void width(double w) { m_stroker.width(m_width = w); } + void miter_limit(double ml) { m_stroker.miter_limit(ml); } + void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); } + void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); } + void approximation_scale(double as) { m_stroker.approximation_scale(as); } + + double width() const { return m_width; } + double miter_limit() const { return m_stroker.miter_limit(); } + double inner_miter_limit() const { return m_stroker.inner_miter_limit(); } + double approximation_scale() const { return m_stroker.approximation_scale(); } + + void auto_detect_orientation(bool v) { m_auto_detect = v; } + bool auto_detect_orientation() const { return m_auto_detect; } // Generator interface void remove_all(); void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface - void rewind(unsigned id); + void rewind(unsigned path_id); unsigned vertex(double* x, double* y); private: vcgen_contour(const vcgen_contour&); const vcgen_contour& operator = (const vcgen_contour&); - vertex_storage m_src_vertices; - coord_storage m_out_vertices; - double m_width; - line_join_e m_line_join; - line_join_e m_inner_line_join; - double m_approx_scale; - double m_abs_width; - double m_signed_width; - double m_miter_limit; - double m_inner_miter_limit; - status_e m_status; - unsigned m_src_vertex; - unsigned m_out_vertex; - unsigned m_closed; - unsigned m_orientation; - bool m_auto_detect; + math_stroke m_stroker; + double m_width; + vertex_storage m_src_vertices; + coord_storage m_out_vertices; + status_e m_status; + unsigned m_src_vertex; + unsigned m_out_vertex; + unsigned m_closed; + unsigned m_orientation; + bool m_auto_detect; }; } diff --git a/headers/libs/agg/agg_vcgen_dash.h b/headers/libs/agg/agg_vcgen_dash.h index 0e9d7d0e4d..c87dce4c81 100755 --- a/headers/libs/agg/agg_vcgen_dash.h +++ b/headers/libs/agg/agg_vcgen_dash.h @@ -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_vertex_sequence.h" -#include "agg_vertex_iterator.h" namespace agg { @@ -32,7 +31,7 @@ namespace agg // class vcgen_dash { - enum + enum max_dashes_e { max_dashes = 32 }; @@ -62,14 +61,9 @@ namespace agg void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface - void rewind(unsigned id); + void rewind(unsigned path_id); unsigned vertex(double* x, double* y); - typedef vcgen_dash source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: vcgen_dash(const vcgen_dash&); const vcgen_dash& operator = (const vcgen_dash&); diff --git a/headers/libs/agg/agg_vcgen_markers_term.h b/headers/libs/agg/agg_vcgen_markers_term.h index 2bfef0c1d3..ee1e74e3eb 100755 --- a/headers/libs/agg/agg_vcgen_markers_term.h +++ b/headers/libs/agg/agg_vcgen_markers_term.h @@ -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,7 +18,6 @@ #include "agg_basics.h" #include "agg_vertex_sequence.h" -#include "agg_vertex_iterator.h" namespace agg { @@ -39,14 +38,9 @@ namespace agg void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface - void rewind(unsigned id); + void rewind(unsigned path_id); unsigned vertex(double* x, double* y); - typedef vcgen_markers_term source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: vcgen_markers_term(const vcgen_markers_term&); const vcgen_markers_term& operator = (const vcgen_markers_term&); @@ -59,7 +53,7 @@ namespace agg coord_type(double x_, double y_) : x(x_), y(y_) {} }; - typedef pod_deque coord_storage; + typedef pod_bvector coord_storage; coord_storage m_markers; unsigned m_curr_id; diff --git a/headers/libs/agg/agg_vcgen_smooth_poly1.h b/headers/libs/agg/agg_vcgen_smooth_poly1.h index 346a38aca4..80fc0fb796 100755 --- a/headers/libs/agg/agg_vcgen_smooth_poly1.h +++ b/headers/libs/agg/agg_vcgen_smooth_poly1.h @@ -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 add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface - void rewind(unsigned id); + void rewind(unsigned path_id); unsigned vertex(double* x, double* y); private: diff --git a/headers/libs/agg/agg_vcgen_stroke.h b/headers/libs/agg/agg_vcgen_stroke.h index 5fa2ff475b..778223fe40 100755 --- a/headers/libs/agg/agg_vcgen_stroke.h +++ b/headers/libs/agg/agg_vcgen_stroke.h @@ -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_VCGEN_STROKE_INCLUDED #include "agg_math_stroke.h" -#include "agg_vertex_iterator.h" namespace agg @@ -48,28 +47,28 @@ namespace agg public: typedef vertex_sequence vertex_storage; - typedef pod_deque coord_storage; + typedef pod_bvector coord_storage; vcgen_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_line_join(line_join_e lj) { m_inner_line_join = lj; } + void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); } + void line_join(line_join_e lj) { m_stroker.line_join(lj); } + void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); } - line_cap_e line_cap() const { return m_line_cap; } - line_join_e line_join() const { return m_line_join; } - line_join_e inner_line_join() const { return m_inner_line_join; } + line_cap_e line_cap() const { return m_stroker.line_cap(); } + line_join_e line_join() const { return m_stroker.line_join(); } + inner_join_e inner_join() const { return m_stroker.inner_join(); } - void width(double w) { m_width = w * 0.5; } - 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; } + void width(double w) { m_stroker.width(w); } + void miter_limit(double ml) { m_stroker.miter_limit(ml); } + void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); } + void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); } + void approximation_scale(double as) { m_stroker.approximation_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; } + double width() const { return m_stroker.width(); } + double miter_limit() const { return m_stroker.miter_limit(); } + double inner_miter_limit() const { return m_stroker.inner_miter_limit(); } + double approximation_scale() const { return m_stroker.approximation_scale(); } void shorten(double s) { m_shorten = s; } double shorten() const { return m_shorten; } @@ -79,33 +78,22 @@ namespace agg void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface - void rewind(unsigned id); + void rewind(unsigned path_id); unsigned vertex(double* x, double* y); - typedef vcgen_stroke source_type; - typedef vertex_iterator iterator; - iterator begin(unsigned id) { return iterator(*this, id); } - iterator end() { return iterator(path_cmd_stop); } - private: vcgen_stroke(const vcgen_stroke&); const vcgen_stroke& operator = (const vcgen_stroke&); - vertex_storage m_src_vertices; - coord_storage m_out_vertices; - double m_width; - double m_miter_limit; - double m_inner_miter_limit; - double m_approx_scale; - double m_shorten; - line_cap_e m_line_cap; - line_join_e m_line_join; - line_join_e m_inner_line_join; - unsigned m_closed; - status_e m_status; - status_e m_prev_status; - unsigned m_src_vertex; - unsigned m_out_vertex; + math_stroke m_stroker; + vertex_storage m_src_vertices; + coord_storage m_out_vertices; + double m_shorten; + unsigned m_closed; + status_e m_status; + status_e m_prev_status; + unsigned m_src_vertex; + unsigned m_out_vertex; }; diff --git a/headers/libs/agg/agg_vcgen_vertex_sequence.h b/headers/libs/agg/agg_vcgen_vertex_sequence.h index be873094df..5adc671597 100755 --- a/headers/libs/agg/agg_vcgen_vertex_sequence.h +++ b/headers/libs/agg/agg_vcgen_vertex_sequence.h @@ -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. @@ -43,7 +43,7 @@ namespace agg void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface - void rewind(unsigned id); + void rewind(unsigned path_id); unsigned vertex(double* x, double* y); void shorten(double s) { m_shorten = s; } diff --git a/headers/libs/agg/agg_vertex_iterator.h b/headers/libs/agg/agg_vertex_iterator.h deleted file mode 100644 index 75746dd5d1..0000000000 --- a/headers/libs/agg/agg_vertex_iterator.h +++ /dev/null @@ -1,133 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes: vertex_iterator -// vertex_source_adaptor -// vertex_source_adaptor_with_id -// -//---------------------------------------------------------------------------- -#ifndef AGG_VERTEX_ITERATOR_INCLUDED -#define AGG_VERTEX_ITERATOR_INCLUDED - -#include "agg_basics.h" - - -namespace agg -{ - - //---------------------------------------------------------vertex_iterator - template class vertex_iterator - { - public: - vertex_iterator() {} - vertex_iterator(unsigned cmd) { m_vertex.cmd = cmd; } - vertex_iterator(const vertex_iterator& i) : m_vs(i.m_vs), m_vertex(i.m_vertex) {} - vertex_iterator(VertexSource& vs, unsigned id) : m_vs(&vs) - { - m_vs->rewind(id); - m_vertex.cmd = m_vs->vertex(&m_vertex.x, &m_vertex.y); - } - vertex_iterator& operator++() - { - m_vertex.cmd = m_vs->vertex(&m_vertex.x, &m_vertex.y); - return *this; - } - - const vertex_type& operator*() const { return m_vertex; } - const vertex_type* operator->() const { return &m_vertex; } - - bool operator != (const vertex_iterator& i) - { - return m_vertex.cmd != i.m_vertex.cmd; - } - - private: - VertexSource* m_vs; - vertex_type m_vertex; - }; - - - //---------------------------------------------------vertex_source_adaptor - template class vertex_source_adaptor - { - public: - vertex_source_adaptor(const VertexContainer& container) : - m_container(&container) {} - - void rewind(unsigned) - { - m_iterator = m_container->begin(); - m_end = m_container->end(); - } - - unsigned vertex(double* x, double* y) - { - unsigned cmd = path_cmd_stop; - if(m_iterator != m_end) - { - *x = m_iterator->x; - *y = m_iterator->y; - cmd = m_iterator->cmd; - ++m_iterator; - } - return cmd; - } - - private: - const VertexContainer* m_container; - typename VertexContainer::const_iterator m_iterator; - typename VertexContainer::const_iterator m_end; - }; - - - - //-------------------------------------------vertex_source_adaptor_with_id - template class vertex_source_adaptor_with_id - { - public: - vertex_source_adaptor_with_id(const VertexContainer& container) : - m_container(&container) {} - - void rewind(unsigned id) - { - m_iterator = m_container->begin(id); - m_end = m_container->end(); - } - - unsigned vertex(double* x, double* y) - { - unsigned cmd = path_cmd_stop; - if(m_iterator != m_end) - { - *x = m_iterator->x; - *y = m_iterator->y; - cmd = m_iterator->cmd; - ++m_iterator; - } - return cmd; - } - - private: - const VertexContainer* m_container; - typename VertexContainer::const_iterator m_iterator; - typename VertexContainer::const_iterator m_end; - }; - - - -} - - -#endif diff --git a/headers/libs/agg/agg_vertex_sequence.h b/headers/libs/agg/agg_vertex_sequence.h index b650f5e7aa..2ad0701b37 100644 --- a/headers/libs/agg/agg_vertex_sequence.h +++ b/headers/libs/agg/agg_vertex_sequence.h @@ -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,10 +27,10 @@ namespace agg { //----------------------------------------------------------vertex_sequence - // Modified agg::pod_deque. The data is interpreted as a sequence of vertices. - // It means that the type T must expose: + // Modified agg::pod_bvector. The data is interpreted as a sequence + // of vertices. It means that the type T must expose: // - // bool operator() (const T& val) + // bool T::operator() (const T& val) // // that is called every time new vertex is being added. The main purpose // of this operator is the possibility to calculate some values during @@ -64,10 +64,10 @@ namespace agg // necessary. //------------------------------------------------------------------------ template - class vertex_sequence : public pod_deque + class vertex_sequence : public pod_bvector { public: - typedef pod_deque base_type; + typedef pod_bvector base_type; void add(const T& val); void modify_last(const T& val); @@ -124,10 +124,6 @@ namespace agg } - - // Coinciding points maximal distance (Epsilon) - const double vertex_dist_epsilon = 1e-14; - //-------------------------------------------------------------vertex_dist // Vertex (x, y) with the distance to the next one. The last vertex has // distance between the last and the first points if the polygon is closed diff --git a/headers/libs/agg/agg_vpgen_clip_polygon.h b/headers/libs/agg/agg_vpgen_clip_polygon.h index 835ae57c28..ded754e211 100644 --- a/headers/libs/agg/agg_vpgen_clip_polygon.h +++ b/headers/libs/agg/agg_vpgen_clip_polygon.h @@ -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. diff --git a/headers/libs/agg/agg_vpgen_clip_polyline.h b/headers/libs/agg/agg_vpgen_clip_polyline.h index 87dbffe88f..b070a7759e 100644 --- a/headers/libs/agg/agg_vpgen_clip_polyline.h +++ b/headers/libs/agg/agg_vpgen_clip_polyline.h @@ -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,9 @@ namespace agg m_clip_box(0, 0, 1, 1), m_x1(0), m_y1(0), - m_f1(0), - m_x2(0), - m_y2(0), - m_f2(0), m_num_vertices(0), - m_vertex(0) + m_vertex(0), + m_move_to(false) { } @@ -50,7 +47,6 @@ namespace agg m_clip_box.normalize(); } - double x1() const { return m_clip_box.x1; } double y1() const { return m_clip_box.y1; } double x2() const { return m_clip_box.x2; } @@ -64,55 +60,16 @@ namespace agg void line_to(double x, double y); unsigned vertex(double* x, double* y); - private: - enum clipping_flags_def - { - clip_x1 = 1, - clip_x2 = 2, - clip_y1 = 4, - clip_y2 = 8 - }; - - // Determine the clipping code of the vertex according to the - // Cyrus-Beck line clipping algorithm - //-------------------------------------------------------------------- - unsigned clipping_flags_x(double x) - { - unsigned f = 0; - if(x < m_clip_box.x1) f |= clip_x1; - if(x > m_clip_box.x2) f |= clip_x2; - return f; - } - - unsigned clipping_flags_y(double y) - { - unsigned f = 0; - if(y < m_clip_box.y1) f |= clip_y1; - if(y > m_clip_box.y2) f |= clip_y2; - return f; - } - - unsigned clipping_flags(double x, double y) - { - return clipping_flags_x(x) | clipping_flags_y(y); - } - - bool move_point(double& x, double& y, unsigned& flags); - void clip_line_segment(); - private: rect_d m_clip_box; double m_x1; double m_y1; - unsigned m_f1; - double m_x2; - double m_y2; - unsigned m_f2; double m_x[2]; double m_y[2]; unsigned m_cmd[2]; unsigned m_num_vertices; unsigned m_vertex; + bool m_move_to; }; } diff --git a/headers/libs/agg/agg_vpgen_segmentator.h b/headers/libs/agg/agg_vpgen_segmentator.h index 6564aa064d..29b3c9fa6f 100755 --- a/headers/libs/agg/agg_vpgen_segmentator.h +++ b/headers/libs/agg/agg_vpgen_segmentator.h @@ -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. diff --git a/headers/libs/agg/ctrl/agg_bezier_ctrl.h b/headers/libs/agg/ctrl/agg_bezier_ctrl.h deleted file mode 100644 index d3f030c869..0000000000 --- a/headers/libs/agg/ctrl/agg_bezier_ctrl.h +++ /dev/null @@ -1,112 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes bezier_ctrl_impl, bezier_ctrl -// -//---------------------------------------------------------------------------- - -#ifndef AGG_BEZIER_CTRL_INCLUDED -#define AGG_BEZIER_CTRL_INCLUDED - -#include "agg_math.h" -#include "agg_ellipse.h" -#include "agg_trans_affine.h" -#include "agg_color_rgba.h" -#include "agg_conv_stroke.h" -#include "agg_conv_curve.h" -#include "agg_polygon_ctrl.h" - - -namespace agg -{ - - //--------------------------------------------------------bezier_ctrl_impl - class bezier_ctrl_impl : public ctrl - { - public: - bezier_ctrl_impl(); - - void curve(double x1, double y1, - double x2, double y2, - double x3, double y3, - double x4, double y4); - curve4& curve(); - - double x1() const { return m_poly.xn(0); } - double y1() const { return m_poly.yn(0); } - double x2() const { return m_poly.xn(1); } - double y2() const { return m_poly.yn(1); } - double x3() const { return m_poly.xn(2); } - double y3() const { return m_poly.yn(2); } - double x4() const { return m_poly.xn(3); } - double y4() const { return m_poly.yn(3); } - - void line_width(double w) { m_stroke.width(w); } - double line_width() const { return m_stroke.width(); } - - void point_radius(double r) { m_poly.point_radius(r); } - double point_radius() const { return m_poly.point_radius(); } - - virtual bool in_rect(double x, double y) const; - virtual bool on_mouse_button_down(double x, double y); - virtual bool on_mouse_button_up(double x, double y); - virtual bool on_mouse_move(double x, double y, bool button_flag); - virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); - - // Vertex source interface - unsigned num_paths() { return 7; }; - void rewind(unsigned id); - unsigned vertex(double* x, double* y); - - - private: - curve4 m_curve; - ellipse m_ellipse; - conv_stroke m_stroke; - polygon_ctrl_impl m_poly; - unsigned m_idx; - }; - - - - //----------------------------------------------------------bezier_ctrl - template class bezier_ctrl : public bezier_ctrl_impl - { - public: - bezier_ctrl() : - m_color(rgba(0.0, 0.0, 0.0)) - { - } - - void line_color(const ColorT& c) { m_color = c; } - const ColorT& color(unsigned i) const { return m_color; } - - private: - bezier_ctrl(const bezier_ctrl&); - const bezier_ctrl& operator = (const bezier_ctrl&); - - ColorT m_color; - }; - - - - - -} - - - -#endif - diff --git a/headers/libs/agg/ctrl/agg_cbox_ctrl.h b/headers/libs/agg/ctrl/agg_cbox_ctrl.h deleted file mode 100644 index d1aa5a43fd..0000000000 --- a/headers/libs/agg/ctrl/agg_cbox_ctrl.h +++ /dev/null @@ -1,112 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes cbox_ctrl_impl, cbox_ctrl -// -//---------------------------------------------------------------------------- - -#ifndef AGG_CBOX_CTRL_INCLUDED -#define AGG_CBOX_CTRL_INCLUDED - -#include "agg_basics.h" -#include "agg_conv_stroke.h" -#include "agg_gsv_text.h" -#include "agg_trans_affine.h" -#include "agg_color_rgba.h" -#include "agg_ctrl.h" - - - -namespace agg -{ - - //----------------------------------------------------------cbox_ctrl_impl - class cbox_ctrl_impl : public ctrl - { - public: - cbox_ctrl_impl(double x, double y, const char* label, bool flip_y=false); - - void text_thickness(double t) { m_text_thickness = t; } - void text_size(double h, double w=0.0); - - const char* label() { return m_label; } - void label(const char* l); - - bool status() const { return m_status; } - void status(bool st) { m_status = st; } - - virtual bool in_rect(double x, double y) const; - virtual bool on_mouse_button_down(double x, double y); - virtual bool on_mouse_button_up(double x, double y); - virtual bool on_mouse_move(double x, double y, bool button_flag); - virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); - - // Vertex soutce interface - unsigned num_paths() { return 3; }; - void rewind(unsigned id); - unsigned vertex(double* x, double* y); - - private: - double m_text_thickness; - double m_text_height; - double m_text_width; - char m_label[128]; - bool m_status; - double m_vx[32]; - double m_vy[32]; - - gsv_text m_text; - conv_stroke m_text_poly; - - unsigned m_idx; - unsigned m_vertex; - }; - - - //----------------------------------------------------------cbox_ctrl_impl - template class cbox_ctrl : public cbox_ctrl_impl - { - public: - cbox_ctrl(double x, double y, const char* label, bool flip_y=false) : - cbox_ctrl_impl(x, y, label, flip_y), - m_text_color(rgba(0.0, 0.0, 0.0)), - m_inactive_color(rgba(0.0, 0.0, 0.0)), - m_active_color(rgba(0.4, 0.0, 0.0)) - { - m_colors[0] = &m_inactive_color; - m_colors[1] = &m_text_color; - m_colors[2] = &m_active_color; - } - - void text_color(const ColorT& c) { m_text_color = c; } - void inactive_color(const ColorT& c) { m_inactive_color = c; } - void active_color(const ColorT& c) { m_active_color = c; } - - const ColorT& color(unsigned i) const { return *m_colors[i]; } - - private: - cbox_ctrl(const cbox_ctrl&); - const cbox_ctrl& operator = (const cbox_ctrl&); - - ColorT m_text_color; - ColorT m_inactive_color; - ColorT m_active_color; - ColorT* m_colors[3]; - }; - - -} - -#endif diff --git a/headers/libs/agg/ctrl/agg_ctrl.h b/headers/libs/agg/ctrl/agg_ctrl.h deleted file mode 100644 index 34a57a64cc..0000000000 --- a/headers/libs/agg/ctrl/agg_ctrl.h +++ /dev/null @@ -1,101 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Function render_ctrl -// -//---------------------------------------------------------------------------- - -#ifndef AGG_CTRL_INCLUDED -#define AGG_CTRL_INCLUDED - -#include "agg_trans_affine.h" -#include "agg_renderer_scanline.h" - -namespace agg -{ - - //--------------------------------------------------------------------ctrl - class ctrl - { - public: - //-------------------------------------------------------------------- - virtual ~ctrl() {} - ctrl(double x1, double y1, double x2, double y2, bool flip_y) : - m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2), - m_flip_y(flip_y), - m_mtx(0) - { - } - - //-------------------------------------------------------------------- - virtual bool in_rect(double x, double y) const = 0; - virtual bool on_mouse_button_down(double x, double y) = 0; - virtual bool on_mouse_button_up(double x, double y) = 0; - virtual bool on_mouse_move(double x, double y, bool button_flag) = 0; - virtual bool on_arrow_keys(bool left, bool right, bool down, bool up) = 0; - - //-------------------------------------------------------------------- - void transform(const trans_affine& mtx) { m_mtx = &mtx; } - void no_transform() { m_mtx = 0; } - - //-------------------------------------------------------------------- - void transform_xy(double* x, double* y) const - { - if(m_flip_y) *y = m_y1 + m_y2 - *y; - if(m_mtx) m_mtx->transform(x, y); - } - - //-------------------------------------------------------------------- - void inverse_transform_xy(double* x, double* y) const - { - if(m_mtx) m_mtx->inverse_transform(x, y); - if(m_flip_y) *y = m_y1 + m_y2 - *y; - } - - private: - ctrl(const ctrl&); - const ctrl& operator = (const ctrl&); - - protected: - double m_x1; - double m_y1; - double m_x2; - double m_y2; - - private: - bool m_flip_y; - const trans_affine* m_mtx; - }; - - - //-------------------------------------------------------------------- - template - void render_ctrl(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c) - { - unsigned i; - for(i = 0; i < c.num_paths(); i++) - { - ras.reset(); - ras.add_path(c, i); - r.color(c.color(i)); - render_scanlines(ras, sl, r); - } - } - - -} - - -#endif diff --git a/headers/libs/agg/ctrl/agg_gamma_ctrl.h b/headers/libs/agg/ctrl/agg_gamma_ctrl.h deleted file mode 100644 index 1f3d058797..0000000000 --- a/headers/libs/agg/ctrl/agg_gamma_ctrl.h +++ /dev/null @@ -1,170 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// class gamma_ctrl -// -//---------------------------------------------------------------------------- - -#ifndef AGG_GAMMA_CTRL_INCLUDED -#define AGG_GAMMA_CTRL_INCLUDED - -#include "agg_basics.h" -#include "agg_gamma_spline.h" -#include "agg_ellipse.h" -#include "agg_conv_stroke.h" -#include "agg_gsv_text.h" -#include "agg_trans_affine.h" -#include "agg_color_rgba.h" -#include "agg_ctrl.h" - -namespace agg -{ - //------------------------------------------------------------------------ - // Class that can be used to create an interactive control to set up - // gamma arrays. - //------------------------------------------------------------------------ - class gamma_ctrl_impl : public ctrl - { - public: - gamma_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); - - // Set other parameters - void border_width(double t, double extra=0.0); - void curve_width(double t) { m_curve_width = t; } - void grid_width(double t) { m_grid_width = t; } - void text_thickness(double t) { m_text_thickness = t; } - void text_size(double h, double w=0.0); - void point_size(double s) { m_point_size = s; } - - // Event handlers. Just call them if the respective events - // in your system occure. The functions return true if redrawing - // is required. - virtual bool in_rect(double x, double y) const; - virtual bool on_mouse_button_down(double x, double y); - virtual bool on_mouse_button_up(double x, double y); - virtual bool on_mouse_move(double x, double y, bool button_flag); - virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); - - void change_active_point(); - - // A copy of agg::gamma_spline interface - void values(double kx1, double ky1, double kx2, double ky2); - void values(double* kx1, double* ky1, double* kx2, double* ky2) const; - const unsigned char* gamma() const { return m_gamma_spline.gamma(); } - double y(double x) const { return m_gamma_spline.y(x); } - double operator() (double x) const { return m_gamma_spline.y(x); } - const gamma_spline& get_gamma_spline() const { return m_gamma_spline; } - - // Vertex soutce interface - unsigned num_paths() { return 7; } - void rewind(unsigned idx); - unsigned vertex(double* x, double* y); - - private: - void calc_spline_box(); - void calc_points(); - void calc_values(); - - gamma_spline m_gamma_spline; - double m_border_width; - double m_border_extra; - double m_curve_width; - double m_grid_width; - double m_text_thickness; - double m_point_size; - double m_text_height; - double m_text_width; - double m_xc1; - double m_yc1; - double m_xc2; - double m_yc2; - double m_xs1; - double m_ys1; - double m_xs2; - double m_ys2; - double m_xt1; - double m_yt1; - double m_xt2; - double m_yt2; - conv_stroke m_curve_poly; - ellipse m_ellipse; - gsv_text m_text; - conv_stroke m_text_poly; - unsigned m_idx; - unsigned m_vertex; - double m_vx[32]; - double m_vy[32]; - double m_xp1; - double m_yp1; - double m_xp2; - double m_yp2; - bool m_p1_active; - unsigned m_mouse_point; - double m_pdx; - double m_pdy; - }; - - - - template class gamma_ctrl : public gamma_ctrl_impl - { - public: - gamma_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : - gamma_ctrl_impl(x1, y1, x2, y2, flip_y), - m_background_color(rgba(1.0, 1.0, 0.9)), - m_border_color(rgba(0.0, 0.0, 0.0)), - m_curve_color(rgba(0.0, 0.0, 0.0)), - m_grid_color(rgba(0.2, 0.2, 0.0)), - m_inactive_pnt_color(rgba(0.0, 0.0, 0.0)), - m_active_pnt_color(rgba(1.0, 0.0, 0.0)), - m_text_color(rgba(0.0, 0.0, 0.0)) - { - m_colors[0] = &m_background_color; - m_colors[1] = &m_border_color; - m_colors[2] = &m_curve_color; - m_colors[3] = &m_grid_color; - m_colors[4] = &m_inactive_pnt_color; - m_colors[5] = &m_active_pnt_color; - m_colors[6] = &m_text_color; - } - - // Set colors - void background_color(const ColorT& c) { m_background_color = c; } - void border_color(const ColorT& c) { m_border_color = c; } - void curve_color(const ColorT& c) { m_curve_color = c; } - void grid_color(const ColorT& c) { m_grid_color = c; } - void inactive_pnt_color(const ColorT& c) { m_inactive_pnt_color = c; } - void active_pnt_color(const ColorT& c) { m_active_pnt_color = c; } - void text_color(const ColorT& c) { m_text_color = c; } - const ColorT& color(unsigned i) const { return *m_colors[i]; } - - private: - gamma_ctrl(const gamma_ctrl&); - const gamma_ctrl& operator = (const gamma_ctrl&); - - ColorT m_background_color; - ColorT m_border_color; - ColorT m_curve_color; - ColorT m_grid_color; - ColorT m_inactive_pnt_color; - ColorT m_active_pnt_color; - ColorT m_text_color; - ColorT* m_colors[7]; - }; - - -} - -#endif diff --git a/headers/libs/agg/ctrl/agg_gamma_spline.h b/headers/libs/agg/ctrl/agg_gamma_spline.h deleted file mode 100644 index 28e735b7d3..0000000000 --- a/headers/libs/agg/ctrl/agg_gamma_spline.h +++ /dev/null @@ -1,95 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// class gamma_spline -// -//---------------------------------------------------------------------------- - -#ifndef AGG_GAMMA_SPLINE_INCLUDED -#define AGG_GAMMA_SPLINE_INCLUDED - -#include "agg_basics.h" -#include "agg_bspline.h" - -namespace agg -{ - - //------------------------------------------------------------------------ - // Class-helper for calculation gamma-correction arrays. A gamma-correction - // array is an array of 256 unsigned chars that determine the actual values - // of Anti-Aliasing for each pixel coverage value from 0 to 255. If all the - // values in the array are equal to its index, i.e. 0,1,2,3,... there's - // no gamma-correction. Class agg::polyfill allows you to use custom - // gamma-correction arrays. You can calculate it using any approach, and - // class gamma_spline allows you to calculate almost any reasonable shape - // of the gamma-curve with using only 4 values - kx1, ky1, kx2, ky2. - // - // kx2 - // +----------------------------------+ - // | | | . | - // | | | . | ky2 - // | | . ------| - // | | . | - // | | . | - // |----------------.|----------------| - // | . | | - // | . | | - // |-------. | | - // ky1 | . | | | - // | . | | | - // +----------------------------------+ - // kx1 - // - // Each value can be in range [0...2]. Value 1.0 means one quarter of the - // bounding rectangle. Function values() calculates the curve by these - // 4 values. After calling it one can get the gamma-array with call gamma(). - // Class also supports the vertex source interface, i.e rewind() and - // vertex(). It's made for convinience and used in class gamma_ctrl. - // Before calling rewind/vertex one must set the bounding box - // box() using pixel coordinates. - //------------------------------------------------------------------------ - - class gamma_spline - { - public: - gamma_spline(); - - void values(double kx1, double ky1, double kx2, double ky2); - const unsigned char* gamma() const { return m_gamma; } - double y(double x) const; - void values(double* kx1, double* ky1, double* kx2, double* ky2) const; - void box(double x1, double y1, double x2, double y2); - - void rewind(unsigned); - unsigned vertex(double* x, double* y); - - private: - unsigned char m_gamma[256]; - double m_x[4]; - double m_y[4]; - bspline m_spline; - double m_x1; - double m_y1; - double m_x2; - double m_y2; - double m_cur_x; - }; - - - - -} - -#endif diff --git a/headers/libs/agg/ctrl/agg_polygon_ctrl.h b/headers/libs/agg/ctrl/agg_polygon_ctrl.h deleted file mode 100644 index 4d0920f02d..0000000000 --- a/headers/libs/agg/ctrl/agg_polygon_ctrl.h +++ /dev/null @@ -1,166 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes polygon_ctrl_impl, polygon_ctrl -// -//---------------------------------------------------------------------------- - -#ifndef POLYGON_CTRL_INCLUDED -#define POLYGON_CTRL_INCLUDED - -#include "agg_conv_stroke.h" -#include "agg_ellipse.h" -#include "agg_color_rgba.h" -#include "agg_ctrl.h" - -namespace agg -{ - class simple_polygon_vertex_source - { - public: - simple_polygon_vertex_source(const double* polygon, unsigned np, - bool roundoff = false, - bool close = true) : - m_polygon(polygon), - m_num_points(np), - m_vertex(0), - m_roundoff(roundoff), - m_close(close) - { - } - - void close(bool f) { m_close = f; } - bool close() const { return m_close; } - - void rewind(unsigned) - { - m_vertex = 0; - } - - unsigned vertex(double* x, double* y) - { - if(m_vertex > m_num_points) return path_cmd_stop; - if(m_vertex == m_num_points) - { - ++m_vertex; - return path_cmd_end_poly | (m_close ? path_flags_close : 0); - } - *x = m_polygon[m_vertex * 2]; - *y = m_polygon[m_vertex * 2 + 1]; - if(m_roundoff) - { - *x = floor(*x) + 0.5; - *y = floor(*y) + 0.5; - } - ++m_vertex; - return (m_vertex == 1) ? path_cmd_move_to : path_cmd_line_to; - } - - private: - const double* m_polygon; - unsigned m_num_points; - unsigned m_vertex; - bool m_roundoff; - bool m_close; - }; - - - - - class polygon_ctrl_impl : public ctrl - { - public: - ~polygon_ctrl_impl(); - polygon_ctrl_impl(unsigned np, double point_radius=5); - - unsigned num_points() const { return m_num_points; } - double xn(unsigned n) const { return m_polygon[n * 2]; } - double yn(unsigned n) const { return m_polygon[n * 2 + 1]; } - double& xn(unsigned n) { return m_polygon[n * 2]; } - double& yn(unsigned n) { return m_polygon[n * 2 + 1]; } - - const double* polygon() const { return m_polygon; } - - void line_width(double w) { m_stroke.width(w); } - double line_width() const { return m_stroke.width(); } - - void point_radius(double r) { m_point_radius = r; } - double point_radius() const { return m_point_radius; } - - void in_polygon_check(bool f) { m_in_polygon_check = f; } - bool in_polygon_check() const { return m_in_polygon_check; } - - void close(bool f) { m_vs.close(f); } - bool close() const { return m_vs.close(); } - - // Vertex source interface - unsigned num_paths() { return 1; } - void rewind(unsigned id); - unsigned vertex(double* x, double* y); - - virtual bool in_rect(double x, double y) const; - virtual bool on_mouse_button_down(double x, double y); - virtual bool on_mouse_button_up(double x, double y); - virtual bool on_mouse_move(double x, double y, bool button_flag); - virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); - - - private: - bool check_edge(unsigned i, double x, double y) const; - bool point_in_polygon(double x, double y) const; - - double* m_polygon; - unsigned m_num_points; - int m_node; - int m_edge; - simple_polygon_vertex_source m_vs; - conv_stroke m_stroke; - ellipse m_ellipse; - double m_point_radius; - unsigned m_status; - double m_dx; - double m_dy; - bool m_in_polygon_check; - }; - - - - //----------------------------------------------------------polygon_ctrl - template class polygon_ctrl : public polygon_ctrl_impl - { - public: - polygon_ctrl(unsigned np, double point_radius=5) : - polygon_ctrl_impl(np, point_radius), - m_color(rgba(0.0, 0.0, 0.0)) - { - } - - void line_color(const ColorT& c) { m_color = c; } - const ColorT& color(unsigned i) const { return m_color; } - - private: - polygon_ctrl(const polygon_ctrl&); - const polygon_ctrl& operator = (const polygon_ctrl&); - - ColorT m_color; - }; - - - - -} - -#endif - diff --git a/headers/libs/agg/ctrl/agg_rbox_ctrl.h b/headers/libs/agg/ctrl/agg_rbox_ctrl.h deleted file mode 100644 index dce7f7b5b8..0000000000 --- a/headers/libs/agg/ctrl/agg_rbox_ctrl.h +++ /dev/null @@ -1,142 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes rbox_ctrl_impl, rbox_ctrl -// -//---------------------------------------------------------------------------- - -#ifndef AGG_RBOX_CTRL_INCLUDED -#define AGG_RBOX_CTRL_INCLUDED - -#include "agg_basics.h" -#include "agg_ellipse.h" -#include "agg_conv_stroke.h" -#include "agg_gsv_text.h" -#include "agg_trans_affine.h" -#include "agg_color_rgba.h" -#include "agg_ctrl.h" - - - -namespace agg -{ - - //------------------------------------------------------------------------ - class rbox_ctrl_impl : public ctrl - { - public: - ~rbox_ctrl_impl(); - rbox_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); - - void border_width(double t, double extra=0.0); - void text_thickness(double t) { m_text_thickness = t; } - void text_size(double h, double w=0.0); - - void add_item(const char* text); - int cur_item() const { return m_cur_item; } - void cur_item(int i) { m_cur_item = i; } - - virtual bool in_rect(double x, double y) const; - virtual bool on_mouse_button_down(double x, double y); - virtual bool on_mouse_button_up(double x, double y); - virtual bool on_mouse_move(double x, double y, bool button_flag); - virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); - - // Vertex soutce interface - unsigned num_paths() { return 5; }; - void rewind(unsigned id); - unsigned vertex(double* x, double* y); - - private: - void calc_rbox(); - - double m_border_width; - double m_border_extra; - double m_text_thickness; - double m_text_height; - double m_text_width; - char* m_items[32]; - unsigned m_num_items; - int m_cur_item; - - double m_xs1; - double m_ys1; - double m_xs2; - double m_ys2; - - double m_vx[32]; - double m_vy[32]; - unsigned m_draw_item; - double m_dy; - - ellipse m_ellipse; - conv_stroke m_ellipse_poly; - gsv_text m_text; - conv_stroke m_text_poly; - - unsigned m_idx; - unsigned m_vertex; - }; - - - - //------------------------------------------------------------------------ - template class rbox_ctrl : public rbox_ctrl_impl - { - public: - rbox_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : - rbox_ctrl_impl(x1, y1, x2, y2, flip_y), - m_background_color(rgba(1.0, 1.0, 0.9)), - m_border_color(rgba(0.0, 0.0, 0.0)), - m_text_color(rgba(0.0, 0.0, 0.0)), - m_inactive_color(rgba(0.0, 0.0, 0.0)), - m_active_color(rgba(0.4, 0.0, 0.0)) - { - m_colors[0] = &m_background_color; - m_colors[1] = &m_border_color; - m_colors[2] = &m_text_color; - m_colors[3] = &m_inactive_color; - m_colors[4] = &m_active_color; - } - - - void background_color(const ColorT& c) { m_background_color = c; } - void border_color(const ColorT& c) { m_border_color = c; } - void text_color(const ColorT& c) { m_text_color = c; } - void inactive_color(const ColorT& c) { m_inactive_color = c; } - void active_color(const ColorT& c) { m_active_color = c; } - - const ColorT& color(unsigned i) const { return *m_colors[i]; } - - private: - rbox_ctrl(const rbox_ctrl&); - const rbox_ctrl& operator = (const rbox_ctrl&); - - ColorT m_background_color; - ColorT m_border_color; - ColorT m_text_color; - ColorT m_inactive_color; - ColorT m_active_color; - ColorT* m_colors[5]; - }; - - - -} - - - -#endif - diff --git a/headers/libs/agg/ctrl/agg_scale_ctrl.h b/headers/libs/agg/ctrl/agg_scale_ctrl.h deleted file mode 100644 index d9bbe2f131..0000000000 --- a/headers/libs/agg/ctrl/agg_scale_ctrl.h +++ /dev/null @@ -1,142 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes scale_ctrl_impl, scale_ctrl -// -//---------------------------------------------------------------------------- - -#ifndef AGG_SCALE_CTRL_INCLUDED -#define AGG_SCALE_CTRL_INCLUDED - -#include "agg_basics.h" -#include "agg_math.h" -#include "agg_ellipse.h" -#include "agg_trans_affine.h" -#include "agg_color_rgba.h" -#include "agg_ctrl.h" - - -namespace agg -{ - - //------------------------------------------------------------------------ - class scale_ctrl_impl : public ctrl - { - enum move_e - { - move_nothing, - move_value1, - move_value2, - move_slider - }; - - public: - scale_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); - - void border_thickness(double t, double extra=0.0); - - double min_delta() const { return m_min_d; } - void min_delta(double d) { m_min_d = d; } - - double value1() const { return m_value1; } - void value1(double value) { m_value1 = value; } - - double value2() const { return m_value2; } - void value2(double value) { m_value2 = value; } - - virtual bool in_rect(double x, double y) const; - virtual bool on_mouse_button_down(double x, double y); - virtual bool on_mouse_button_up(double x, double y); - virtual bool on_mouse_move(double x, double y, bool button_flag); - virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); - - // Vertex soutce interface - unsigned num_paths() { return 5; }; - void rewind(unsigned id); - unsigned vertex(double* x, double* y); - - private: - void calc_box(); - - double m_border_thickness; - double m_border_extra; - double m_value1; - double m_value2; - double m_min_d; - double m_xs1; - double m_ys1; - double m_xs2; - double m_ys2; - double m_pdx; - move_e m_move_what; - double m_vx[32]; - double m_vy[32]; - - ellipse m_ellipse; - - unsigned m_idx; - unsigned m_vertex; - - }; - - - - //------------------------------------------------------------------------ - template class scale_ctrl : public scale_ctrl_impl - { - public: - scale_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : - scale_ctrl_impl(x1, y1, x2, y2, flip_y), - m_background_color(rgba(1.0, 0.9, 0.8)), - m_border_color(rgba(0.0, 0.0, 0.0)), - m_pointers_color(rgba(0.8, 0.0, 0.0, 0.8)), - m_slider_color(rgba(0.2, 0.1, 0.0, 0.8)) - { - m_colors[0] = &m_background_color; - m_colors[1] = &m_border_color; - m_colors[2] = &m_pointers_color; - m_colors[3] = &m_pointers_color; - m_colors[4] = &m_slider_color; - } - - - void background_color(const ColorT& c) { m_background_color = c; } - void border_color(const ColorT& c) { m_border_color = c; } - void pointers_color(const ColorT& c) { m_pointers_color = c; } - void slider_color(const ColorT& c) { m_slider_color = c; } - - const ColorT& color(unsigned i) const { return *m_colors[i]; } - - private: - scale_ctrl(const scale_ctrl&); - const scale_ctrl& operator = (const scale_ctrl&); - - ColorT m_background_color; - ColorT m_border_color; - ColorT m_pointers_color; - ColorT m_slider_color; - ColorT* m_colors[5]; - }; - - - - - -} - - - -#endif - diff --git a/headers/libs/agg/ctrl/agg_slider_ctrl.h b/headers/libs/agg/ctrl/agg_slider_ctrl.h deleted file mode 100644 index 4adfe4e436..0000000000 --- a/headers/libs/agg/ctrl/agg_slider_ctrl.h +++ /dev/null @@ -1,150 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes slider_ctrl_impl, slider_ctrl -// -//---------------------------------------------------------------------------- - -#ifndef AGG_SLIDER_CTRL_INCLUDED -#define AGG_SLIDER_CTRL_INCLUDED - -#include "agg_basics.h" -#include "agg_math.h" -#include "agg_ellipse.h" -#include "agg_trans_affine.h" -#include "agg_color_rgba.h" -#include "agg_gsv_text.h" -#include "agg_conv_stroke.h" -#include "agg_path_storage.h" -#include "agg_ctrl.h" - - -namespace agg -{ - - //--------------------------------------------------------slider_ctrl_impl - class slider_ctrl_impl : public ctrl - { - public: - slider_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); - - void border_width(double t, double extra=0.0); - - void range(double min, double max) { m_min = min; m_max = max; } - void num_steps(unsigned num) { m_num_steps = num; } - void label(const char* fmt); - void text_thickness(double t) { m_text_thickness = t; } - - bool descending() const { return m_descending; } - void descending(bool v) { m_descending = v; } - - double value() const { return m_value * (m_max - m_min) + m_min; } - void value(double value); - - virtual bool in_rect(double x, double y) const; - virtual bool on_mouse_button_down(double x, double y); - virtual bool on_mouse_button_up(double x, double y); - virtual bool on_mouse_move(double x, double y, bool button_flag); - virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); - - // Vertex source interface - unsigned num_paths() { return 6; }; - void rewind(unsigned id); - unsigned vertex(double* x, double* y); - - private: - void calc_box(); - bool normalize_value(bool preview_value_flag); - - double m_border_width; - double m_border_extra; - double m_text_thickness; - double m_value; - double m_preview_value; - double m_min; - double m_max; - unsigned m_num_steps; - bool m_descending; - char m_label[64]; - double m_xs1; - double m_ys1; - double m_xs2; - double m_ys2; - double m_pdx; - bool m_mouse_move; - double m_vx[32]; - double m_vy[32]; - - ellipse m_ellipse; - - unsigned m_idx; - unsigned m_vertex; - - gsv_text m_text; - conv_stroke m_text_poly; - path_storage m_storage; - - }; - - - - //----------------------------------------------------------slider_ctrl - template class slider_ctrl : public slider_ctrl_impl - { - public: - slider_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : - slider_ctrl_impl(x1, y1, x2, y2, flip_y), - m_background_color(rgba(1.0, 0.9, 0.8)), - m_triangle_color(rgba(0.7, 0.6, 0.6)), - m_text_color(rgba(0.0, 0.0, 0.0)), - m_pointer_preview_color(rgba(0.6, 0.4, 0.4, 0.4)), - m_pointer_color(rgba(0.8, 0.0, 0.0, 0.6)) - { - m_colors[0] = &m_background_color; - m_colors[1] = &m_triangle_color; - m_colors[2] = &m_text_color; - m_colors[3] = &m_pointer_preview_color; - m_colors[4] = &m_pointer_color; - m_colors[5] = &m_text_color; - } - - - void background_color(const ColorT& c) { m_background_color = c; } - void pointer_color(const ColorT& c) { m_pointer_color = c; } - - const ColorT& color(unsigned i) const { return *m_colors[i]; } - - private: - slider_ctrl(const slider_ctrl&); - const slider_ctrl& operator = (const slider_ctrl&); - - ColorT m_background_color; - ColorT m_triangle_color; - ColorT m_text_color; - ColorT m_pointer_preview_color; - ColorT m_pointer_color; - ColorT* m_colors[6]; - }; - - - - - -} - - - -#endif - diff --git a/headers/libs/agg/ctrl/agg_spline_ctrl.h b/headers/libs/agg/ctrl/agg_spline_ctrl.h deleted file mode 100644 index 39aafafccb..0000000000 --- a/headers/libs/agg/ctrl/agg_spline_ctrl.h +++ /dev/null @@ -1,159 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes spline_ctrl_impl, spline_ctrl -// -//---------------------------------------------------------------------------- - -#ifndef AGG_SPLINE_CTRL_INCLUDED -#define AGG_SPLINE_CTRL_INCLUDED - -#include "agg_basics.h" -#include "agg_ellipse.h" -#include "agg_bspline.h" -#include "agg_conv_stroke.h" -#include "agg_path_storage.h" -#include "agg_trans_affine.h" -#include "agg_color_rgba.h" -#include "agg_ctrl.h" - -namespace agg -{ - - //------------------------------------------------------------------------ - // Class that can be used to create an interactive control to set up - // gamma arrays. - //------------------------------------------------------------------------ - class spline_ctrl_impl : public ctrl - { - public: - spline_ctrl_impl(double x1, double y1, double x2, double y2, - unsigned num_pnt, bool flip_y=false); - - // Set other parameters - void border_width(double t, double extra=0.0); - void curve_width(double t) { m_curve_width = t; } - void point_size(double s) { m_point_size = s; } - - // Event handlers. Just call them if the respective events - // in your system occure. The functions return true if redrawing - // is required. - virtual bool in_rect(double x, double y) const; - virtual bool on_mouse_button_down(double x, double y); - virtual bool on_mouse_button_up(double x, double y); - virtual bool on_mouse_move(double x, double y, bool button_flag); - virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); - - void active_point(int i); - - const double* spline() const { return m_spline_values; } - const int8u* spline8() const { return m_spline_values8; } - double value(double x) const; - void value(unsigned idx, double y); - void point(unsigned idx, double x, double y); - void x(unsigned idx, double x) { m_xp[idx] = x; } - void y(unsigned idx, double y) { m_yp[idx] = y; } - double x(unsigned idx) const { return m_xp[idx]; } - double y(unsigned idx) const { return m_yp[idx]; } - void update_spline(); - - // Vertex soutce interface - unsigned num_paths() { return 5; } - void rewind(unsigned id); - unsigned vertex(double* x, double* y); - - private: - void calc_spline_box(); - void calc_curve(); - double calc_xp(unsigned idx); - double calc_yp(unsigned idx); - void set_xp(unsigned idx, double val); - void set_yp(unsigned idx, double val); - - unsigned m_num_pnt; - double m_xp[32]; - double m_yp[32]; - bspline m_spline; - double m_spline_values[256]; - int8u m_spline_values8[256]; - double m_border_width; - double m_border_extra; - double m_curve_width; - double m_point_size; - double m_xs1; - double m_ys1; - double m_xs2; - double m_ys2; - path_storage m_curve_pnt; - conv_stroke m_curve_poly; - ellipse m_ellipse; - unsigned m_idx; - unsigned m_vertex; - double m_vx[32]; - double m_vy[32]; - int m_active_pnt; - int m_move_pnt; - double m_pdx; - double m_pdy; - const trans_affine* m_mtx; - }; - - - template class spline_ctrl : public spline_ctrl_impl - { - public: - spline_ctrl(double x1, double y1, double x2, double y2, - unsigned num_pnt, bool flip_y=false) : - spline_ctrl_impl(x1, y1, x2, y2, num_pnt, flip_y), - m_background_color(rgba(1.0, 1.0, 0.9)), - m_border_color(rgba(0.0, 0.0, 0.0)), - m_curve_color(rgba(0.0, 0.0, 0.0)), - m_inactive_pnt_color(rgba(0.0, 0.0, 0.0)), - m_active_pnt_color(rgba(1.0, 0.0, 0.0)) - { - m_colors[0] = &m_background_color; - m_colors[1] = &m_border_color; - m_colors[2] = &m_curve_color; - m_colors[3] = &m_inactive_pnt_color; - m_colors[4] = &m_active_pnt_color; - } - - // Set colors - void background_color(const ColorT& c) { m_background_color = c; } - void border_color(const ColorT& c) { m_border_color = c; } - void curve_color(const ColorT& c) { m_curve_color = c; } - void inactive_pnt_color(const ColorT& c) { m_inactive_pnt_color = c; } - void active_pnt_color(const ColorT& c) { m_active_pnt_color = c; } - const ColorT& color(unsigned i) const { return *m_colors[i]; } - - private: - spline_ctrl(const spline_ctrl&); - const spline_ctrl& operator = (const spline_ctrl&); - - ColorT m_background_color; - ColorT m_border_color; - ColorT m_curve_color; - ColorT m_inactive_pnt_color; - ColorT m_active_pnt_color; - ColorT* m_colors[5]; - }; - - - - -} - - -#endif diff --git a/headers/libs/agg/platform/agg_platform_support.h b/headers/libs/agg/platform/agg_platform_support.h deleted file mode 100644 index 3de9351051..0000000000 --- a/headers/libs/agg/platform/agg_platform_support.h +++ /dev/null @@ -1,652 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// class platform_support -// -// It's not a part of the AGG library, it's just a helper class to create -// interactive demo examples. Since the examples should not be too complex -// this class is provided to support some very basic interactive graphical -// funtionality, such as putting the rendered image to the window, simple -// keyboard and mouse input, window resizing, setting the window title, -// and catching the "idle" events. -// -// The idea is to have a single header file that does not depend on any -// platform (I hate these endless #ifdef/#elif/#elif.../#endif) and a number -// of different implementations depending on the concrete platform. -// The most popular platforms are: -// -// Windows-32 API -// X-Window API -// SDL library (see http://www.libsdl.org/) -// MacOS C/C++ API -// -// This file does not include any system dependent .h files such as -// windows.h or X11.h, so, your demo applications do not depend on the -// platform. The only file that can #include system dependend headers -// is the implementation file agg_platform_support.cpp. Different -// implementations are placed in different directories, such as -// ~/agg/src/platform/win32 -// ~/agg/src/platform/sdl -// ~/agg/src/platform/X11 -// and so on. -// -// All the system dependent stuff sits in the platform_specific -// class which is forward-declared here but not defined. -// The platform_support class has just a pointer to it and it's -// the responsibility of the implementation to create/delete it. -// This class being defined in the implementation file can have -// any platform dependent stuff such as HWND, X11 Window and so on. -// -//---------------------------------------------------------------------------- - - -#ifndef AGG_PLATFORM_SUPPORT_INCLUDED -#define AGG_PLATFORM_SUPPORT_INCLUDED - - -#include "agg_basics.h" -#include "agg_rendering_buffer.h" -#include "agg_trans_affine.h" -#include "ctrl/agg_ctrl.h" - -namespace agg -{ - - //----------------------------------------------------------window_flag_e - // These are flags used in method init(). Not all of them are - // applicable on different platforms, for example the win32_api - // cannot use a hardware buffer (window_hw_buffer). - // The implementation should simply ignore unsupported flags. - enum window_flag_e - { - window_resize = 1, - window_hw_buffer = 2, - window_keep_aspect_ratio = 4 - }; - - //-----------------------------------------------------------pix_format_e - // Possible formats of the rendering buffer. Initially I thought that it's - // reasonable to create the buffer and the rendering functions in - // accordance with the native pixel format of the system because it - // would have no overhead for pixel format conersion. - // But eventually I came to a conclusion that having a possibility to - // convert pixel formats on demand is a good idea. First, it was X11 where - // there lots of different formats and visuals and it would be great to - // render everything in, say, RGB-24 and display it automatically without - // any additional efforts. The second reason is to have a possibility to - // debug renderers for different pixel formats and colorspaces having only - // one computer and one system. - // - // This stuff is not included into the basic AGG functionality because the - // number of supported pixel formats (and/or colorspaces) can be great and - // if one needs to add new format it would be good only to add new - // rendering files without having to modify any existing ones (a general - // principle of incapsulation and isolation). - // - // Using a particular pixel format doesn't obligatory mean the necessity - // of software conversion. For example, win32 API can natively display - // gray8, 15-bit RGB, 24-bit BGR, and 32-bit BGRA formats. - // This list can be (and will be!) extended in future. - enum pix_format_e - { - pix_format_undefined = 0, // By default. No conversions are applied - pix_format_gray8, // Simple 256 level grayscale - pix_format_rgb555, // 15 bit rgb. Depends on the byte ordering! - pix_format_rgb565, // 16 bit rgb. Depends on the byte ordering! - pix_format_rgb24, // R-G-B, one byte per color component - pix_format_bgr24, // B-G-R, native win32 BMP format. - pix_format_rgba32, // R-G-B-A, one byte per color component - pix_format_argb32, // A-R-G-B, native MAC format - pix_format_abgr32, // A-B-G-R, one byte per color component - pix_format_bgra32, // B-G-R-A, native win32 BMP format - - end_of_pix_formats - }; - - //-------------------------------------------------------------input_flag_e - // Mouse and keyboard flags. They can be different on different platforms - // and the ways they are obtained are also different. But in any case - // the system dependent flags should be mapped into these ones. The meaning - // of that is as follows. For example, if kbd_ctrl is set it means that the - // ctrl key is pressed and being held at the moment. They are also used in - // the overridden methods such as on_mouse_move(), on_mouse_button_down(), - // on_mouse_button_dbl_click(), on_mouse_button_up(), on_key(). - // In the method on_mouse_button_up() the mouse flags have different - // meaning. They mean that the respective button is being released, but - // the meaning of the keyboard flags remains the same. - // There's absolut minimal set of flags is used because they'll be most - // probably supported on different platforms. Even the mouse_right flag - // is restricted because Mac's mice have only one button, but AFAIK - // it can be simulated with holding a special key on the keydoard. - enum input_flag_e - { - mouse_left = 1, - mouse_right = 2, - kbd_shift = 4, - kbd_ctrl = 8 - }; - - //--------------------------------------------------------------key_code_e - // Keyboard codes. There's also a restricted set of codes that are most - // probably supported on different platforms. Any platform dependent codes - // should be converted into these ones. There're only those codes are - // defined that cannot be represented as printable ASCII-characters. - // All printable ASCII-set can be used in a regilar C/C++ manner: - // ' ', 'A', '0' '+' and so on. - // Since the clasas is used for creating very simple demo-applications - // we don't need very rich possibilities here, just basic ones. - // Actually the numeric key codes are taken from the SDL library, so, - // the implementation of the SDL support does not require any mapping. - enum key_code_e - { - // ASCII set. Should be supported everywhere - key_backspace = 8, - key_tab = 9, - key_clear = 12, - key_return = 13, - key_pause = 19, - key_escape = 27, - - // Keypad - key_delete = 127, - key_kp0 = 256, - key_kp1 = 257, - key_kp2 = 258, - key_kp3 = 259, - key_kp4 = 260, - key_kp5 = 261, - key_kp6 = 262, - key_kp7 = 263, - key_kp8 = 264, - key_kp9 = 265, - key_kp_period = 266, - key_kp_divide = 267, - key_kp_multiply = 268, - key_kp_minus = 269, - key_kp_plus = 270, - key_kp_enter = 271, - key_kp_equals = 272, - - // Arrow-keys and stuff - key_up = 273, - key_down = 274, - key_right = 275, - key_left = 276, - key_insert = 277, - key_home = 278, - key_end = 279, - key_page_up = 280, - key_page_down = 281, - - // Functional keys. You'd better avoid using - // f11...f15 in your applications if you want - // the applications to be portable - key_f1 = 282, - key_f2 = 283, - key_f3 = 284, - key_f4 = 285, - key_f5 = 286, - key_f6 = 287, - key_f7 = 288, - key_f8 = 289, - key_f9 = 290, - key_f10 = 291, - key_f11 = 292, - key_f12 = 293, - key_f13 = 294, - key_f14 = 295, - key_f15 = 296, - - // The possibility of using these keys is - // very restricted. Actually it's guaranteed - // only in win32_api and win32_sdl implementations - key_numlock = 300, - key_capslock = 301, - key_scrollock = 302, - - // Phew! - end_of_key_codes - }; - - - //------------------------------------------------------------------------ - // A predeclaration of the platform dependent class. Since we do not - // know anything here the only we can have is just a pointer to this - // class as a data member. It should be created and destroyed explicitely - // in the constructor/destructor of the platform_support class. - // Although the pointer to platform_specific is public the application - // cannot have access to its members or methods since it does not know - // anything about them and it's a perfect incapsulation :-) - class platform_specific; - - - //----------------------------------------------------------ctrl_container - // A helper class that contains pointers to a number of controls. - // This class is used to ease the event handling with controls. - // The implementation should simply call the appropriate methods - // of this class when appropriate events occure. - class ctrl_container - { - enum { max_ctrl = 64 }; - - public: - //-------------------------------------------------------------------- - ctrl_container() : m_num_ctrl(0), m_cur_ctrl(-1) {} - - //-------------------------------------------------------------------- - void add(ctrl& c) - { - if(m_num_ctrl < max_ctrl) - { - m_ctrl[m_num_ctrl++] = &c; - } - } - - //-------------------------------------------------------------------- - bool in_rect(double x, double y) - { - unsigned i; - for(i = 0; i < m_num_ctrl; i++) - { - if(m_ctrl[i]->in_rect(x, y)) return true; - } - return false; - } - - //-------------------------------------------------------------------- - bool on_mouse_button_down(double x, double y) - { - unsigned i; - for(i = 0; i < m_num_ctrl; i++) - { - if(m_ctrl[i]->on_mouse_button_down(x, y)) return true; - } - return false; - } - - //-------------------------------------------------------------------- - bool on_mouse_button_up(double x, double y) - { - unsigned i; - bool flag = false; - for(i = 0; i < m_num_ctrl; i++) - { - if(m_ctrl[i]->on_mouse_button_up(x, y)) flag = true; - } - return flag; - } - - //-------------------------------------------------------------------- - bool on_mouse_move(double x, double y, bool button_flag) - { - unsigned i; - for(i = 0; i < m_num_ctrl; i++) - { - if(m_ctrl[i]->on_mouse_move(x, y, button_flag)) return true; - } - return false; - } - - //-------------------------------------------------------------------- - bool on_arrow_keys(bool left, bool right, bool down, bool up) - { - if(m_cur_ctrl >= 0) - { - return m_ctrl[m_cur_ctrl]->on_arrow_keys(left, right, down, up); - } - return false; - } - - //-------------------------------------------------------------------- - bool set_cur(double x, double y) - { - unsigned i; - for(i = 0; i < m_num_ctrl; i++) - { - if(m_ctrl[i]->in_rect(x, y)) - { - if(m_cur_ctrl != int(i)) - { - m_cur_ctrl = i; - return true; - } - return false; - } - } - if(m_cur_ctrl != -1) - { - m_cur_ctrl = -1; - return true; - } - return false; - } - - private: - ctrl* m_ctrl[max_ctrl]; - unsigned m_num_ctrl; - int m_cur_ctrl; - }; - - - - //---------------------------------------------------------platform_support - // This class is a base one to the apllication classes. It can be used - // as follows: - // - // class the_application : public agg::platform_support - // { - // public: - // the_application(unsigned bpp, bool flip_y) : - // platform_support(bpp, flip_y) - // . . . - // - // //override stuff . . . - // virtual void on_init() - // { - // . . . - // } - // - // virtual void on_draw() - // { - // . . . - // } - // - // virtual void on_resize(int sx, int sy) - // { - // . . . - // } - // // . . . and so on, see virtual functions - // - // - // //any your own stuff . . . - // }; - // - // - // int agg_main(int argc, char* argv[]) - // { - // the_application app(pix_format_rgb24, true); - // app.caption("AGG Example. Lion"); - // - // if(app.init(500, 400, agg::window_resize)) - // { - // return app.run(); - // } - // return 1; - // } - // - // The reason to have agg_main() instead of just main() is that SDL - // for Windows requires including SDL.h if you define main(). Since - // the demo applications cannot rely on any platform/library specific - // stuff it's impossible to include SDL.h into the application files. - // The demo applications are simple and their use is restricted, so, - // this approach is quite reasonable. - // - class platform_support - { - public: - enum { max_images = 16 }; - - // format - see enum pix_format_e {}; - // flip_y - true if you want to have the Y-axis flipped vertically. - platform_support(pix_format_e format, bool flip_y); - virtual ~platform_support(); - - // Setting the windows caption (title). Should be able - // to be called at least before calling init(). - // It's perfect if they can be called anytime. - void caption(const char* cap); - const char* caption() const { return m_caption; } - - //-------------------------------------------------------------------- - // These 3 menthods handle working with images. The image - // formats are the simplest ones, such as .BMP in Windows or - // .ppm in Linux. In the applications the names of the files - // should not have any file extensions. Method load_img() can - // be called before init(), so, the application could be able - // to determine the initial size of the window depending on - // the size of the loaded image. - // The argument "idx" is the number of the image 0...max_images-1 - bool load_img(unsigned idx, const char* file); - bool save_img(unsigned idx, const char* file); - bool create_img(unsigned idx, unsigned width=0, unsigned height=0); - - //-------------------------------------------------------------------- - // init() and run(). See description before the class for details. - // The necessity of calling init() after creation is that it's - // impossible to call the overridden virtual function (on_init()) - // from the constructor. On the other hand it's very useful to have - // some on_init() event handler when the window is created but - // not yet displayed. The rbuf_window() method (see below) is - // accessible from on_init(). - bool init(unsigned width, unsigned height, unsigned flags); - int run(); - - //-------------------------------------------------------------------- - // The very same parameters that were used in the constructor - pix_format_e format() const { return m_format; } - bool flip_y() const { return m_flip_y; } - unsigned bpp() const { return m_bpp; } - - //-------------------------------------------------------------------- - // The following provides a very simple mechanism of doing someting - // in background. It's not multitheading. When whait_mode is true - // the class waits for the events and it does not ever call on_idle(). - // When it's false it calls on_idle() when the event queue is empty. - // The mode can be changed anytime. This mechanism is satisfactory - // for creation very simple animations. - bool wait_mode() const { return m_wait_mode; } - void wait_mode(bool wait_mode) { m_wait_mode = wait_mode; } - - //-------------------------------------------------------------------- - // These two functions control updating of the window. - // force_redraw() is an analog of the Win32 InvalidateRect() function. - // Being called it sets a flag (or sends a message) which results - // in calling on_draw() and updating the content of the window - // when the next event cycle comes. - // update_window() results in just putting immediately the content - // of the currently rendered buffer to the window without calling - // on_draw(). - void force_redraw(); - void update_window(); - - //-------------------------------------------------------------------- - // So, finally, how to draw anythig with AGG? Very simple. - // rbuf_window() returns a reference to the main rendering - // buffer which can be attached to any rendering class. - // rbuf_img() returns a reference to the previously created - // or loaded image buffer (see load_img()). The image buffers - // are not displayed directly, they should be copied to or - // combined somehow with the rbuf_window(). rbuf_window() is - // the only buffer that can be actually displayed. - rendering_buffer& rbuf_window() { return m_rbuf_window; } - rendering_buffer& rbuf_img(unsigned idx) { return m_rbuf_img[idx]; } - - - //-------------------------------------------------------------------- - // Returns file extension used in the implemenation for the particular - // system. - const char* img_ext() const; - - //-------------------------------------------------------------------- - void copy_img_to_window(unsigned idx) - { - if(idx < max_images && rbuf_img(idx).buf()) - { - rbuf_window().copy_from(rbuf_img(idx)); - } - } - - //-------------------------------------------------------------------- - void copy_window_to_img(unsigned idx) - { - if(idx < max_images) - { - create_img(idx, rbuf_window().width(), rbuf_window().height()); - rbuf_img(idx).copy_from(rbuf_window()); - } - } - - //-------------------------------------------------------------------- - void copy_img_to_img(unsigned idx_to, unsigned idx_from) - { - if(idx_from < max_images && - idx_to < max_images && - rbuf_img(idx_from).buf()) - { - create_img(idx_to, - rbuf_img(idx_from).width(), - rbuf_img(idx_from).height()); - rbuf_img(idx_to).copy_from(rbuf_img(idx_from)); - } - } - - //-------------------------------------------------------------------- - // Event handlers. They are not pure functions, so you don't have - // to override them all. - // In my demo applications these functions are defined inside - // the the_application class (implicit inlining) which is in general - // very bad practice, I mean vitual inline methods. At least it does - // not make sence. - // But in this case it's quite appropriate bacause we have the only - // instance of the the_application class and it is in the same file - // where this class is defined. - virtual void on_init(); - virtual void on_resize(int sx, int sy); - virtual void on_idle(); - virtual void on_mouse_move(int x, int y, unsigned flags); - virtual void on_mouse_button_down(int x, int y, unsigned flags); - virtual void on_mouse_button_up(int x, int y, unsigned flags); - virtual void on_key(int x, int y, unsigned key, unsigned flags); - virtual void on_ctrl_change(); - virtual void on_draw(); - virtual void on_post_draw(void* raw_handler); - - //-------------------------------------------------------------------- - // Adding control elements. A control element once added will be - // working and reacting to the mouse and keyboard events. Still, you - // will have to render them in the on_draw() using function - // render_ctrl() because platform_support doesn't know anything about - // renderers you use. The controls will be also scaled automatically - // if they provide a proper scaling mechanism (all the controls - // included into the basic AGG package do). - // If you don't need a particular control to be scaled automatically - // call ctrl::no_transform() after adding. - void add_ctrl(ctrl& c) { m_ctrls.add(c); c.transform(m_resize_mtx); } - - //-------------------------------------------------------------------- - // Auxiliary functions. trans_affine_resizing() modifier sets up the resizing - // matrix on the basis of the given width and height and the initial - // width and height of the window. The implementation should simply - // call this function every time when it catches the resizing event - // passing in the new values of width and height of the window. - // Nothing prevents you from "cheating" the scaling matrix if you - // call this function from somewhere with wrong arguments. - // trans_affine_resizing() accessor simply returns current resizing matrix - // which can be used to apply additional scaling of any of your - // stuff when the window is being resized. - // width(), height(), initial_width(), and initial_height() must be - // clear to understand with no comments :-) - void trans_affine_resizing(int width, int height) - { - if(m_window_flags & window_keep_aspect_ratio) - { - double sx = double(width) / double(m_initial_width); - double sy = double(height) / double(m_initial_height); - if(sy < sx) sx = sy; - m_resize_mtx = trans_affine_scaling(sx, sx); - } - else - { - m_resize_mtx = trans_affine_scaling( - double(width) / double(m_initial_width), - double(height) / double(m_initial_height)); - } - } - const trans_affine& trans_affine_resizing() const { return m_resize_mtx; } - double width() const { return m_rbuf_window.width(); } - double height() const { return m_rbuf_window.height(); } - double initial_width() const { return m_initial_width; } - double initial_height() const { return m_initial_height; } - - //-------------------------------------------------------------------- - // Get raw display handler depending on the system. - // For win32 its an HDC, for other systems it can be a pointer to some - // structure. See the implementation files for detals. - // It's provided "as is", so, first you should check if it's not null. - // If it's null the raw_display_handler is not supported. Also, there's - // no guarantee that this function is implemented, so, in some - // implementations you may have simply an unresolved symbol when linking. - void* raw_display_handler(); - - //-------------------------------------------------------------------- - // display message box or print the message to the console - // (depending on implementation) - void message(const char* msg); - - //-------------------------------------------------------------------- - // Stopwatch functions. Function elapsed_time() returns time elapsed - // since the latest start_timer() invocation in millisecods. - // The resolutoin depends on the implementation. - // In Win32 it uses QueryPerformanceFrequency() / QueryPerformanceCounter(). - void start_timer(); - double elapsed_time() const; - - //-------------------------------------------------------------------- - // Get the full file name. In most cases it simply returns - // file_name. As it's appropriate in many systems if you open - // a file by its name without specifying the path, it tries to - // open it in the current directory. The demos usually expect - // all the supplementary files to be placed in the current - // directory, that is usually coincides with the directory where - // the the executable is. However, in some systems (BeOS) it's not so. - // For those kinds of systems full_file_name() can help access files - // preserving commonly used policy. - // So, it's a good idea to use in the demos the following: - // FILE* fd = fopen(full_file_name("some.file"), "r"); - // instead of - // FILE* fd = fopen("some.file", "r"); - const char* full_file_name(const char* file_name); - - public: - platform_specific* m_specific; - ctrl_container m_ctrls; - - // Sorry, I'm too tired to descibe the private - // data membders. See the implementations for different - // platforms for details. - private: - platform_support(const platform_support&); - const platform_support& operator = (const platform_support&); - - pix_format_e m_format; - unsigned m_bpp; - rendering_buffer m_rbuf_window; - rendering_buffer m_rbuf_img[max_images]; - unsigned m_window_flags; - bool m_wait_mode; - bool m_flip_y; - char m_caption[256]; - int m_initial_width; - int m_initial_height; - trans_affine m_resize_mtx; - }; - - -} - - - -#endif - diff --git a/src/apps/icon-o-matic/shape/VectorPath.cpp b/src/apps/icon-o-matic/shape/VectorPath.cpp index 4ce9e1eb76..488ec315f3 100644 --- a/src/apps/icon-o-matic/shape/VectorPath.cpp +++ b/src/apps/icon-o-matic/shape/VectorPath.cpp @@ -464,8 +464,8 @@ VectorPath::CountPoints() const static float distance_to_curve(const BPoint& p, const BPoint& a, const BPoint& aOut, const BPoint& bIn, const BPoint& b) { - agg::curve4 curve(a.x, a.y, aOut.x, aOut.y, - bIn.x, bIn.y, b.x, b.y); + agg::curve4_inc curve(a.x, a.y, aOut.x, aOut.y, + bIn.x, bIn.y, b.x, b.y); float segDist = FLT_MAX; double x1, y1, x2, y2; @@ -684,8 +684,7 @@ VectorPath::Iterate(Iterator* iterator, float smoothScale) const if (fPointCount > 1) { // generate a curve for each segment of the path // then iterate over the segments of the curve -// agg::curve4_inc curve; -agg::curve4 curve; + agg::curve4_inc curve; for (int32 i = 0; i < fPointCount - 1; i++) { iterator->MoveTo(fPath[i].point); diff --git a/src/libs/agg/Jamfile b/src/libs/agg/Jamfile index 04b0eda069..c59a0a23fe 100644 --- a/src/libs/agg/Jamfile +++ b/src/libs/agg/Jamfile @@ -3,22 +3,14 @@ SubDir HAIKU_TOP src libs agg ; SetSubDirSupportedPlatformsBeOSCompatible ; AddSubDirSupportedPlatforms libbe_test ; -UseFreeTypeHeaders ; UseLibraryHeaders agg ; SubDirCcFlags -w ; SubDirC++Flags -w ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) font_freetype ] ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) gpc ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) src ] ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) src ctrl ] ; -#SharedLibrary libagg.so : StaticLibrary libagg.a : - # font_freetype - agg_font_freetype.cpp - # src agg_arc.cpp agg_arrowhead.cpp @@ -30,8 +22,6 @@ StaticLibrary libagg.a : agg_image_filters.cpp agg_line_aa_basics.cpp agg_line_profile_aa.cpp - agg_path_storage.cpp - agg_rasterizer_scanline_aa.cpp agg_rounded_rect.cpp agg_sqrt_tables.cpp agg_trans_affine.cpp @@ -47,23 +37,5 @@ StaticLibrary libagg.a : agg_vpgen_clip_polygon.cpp agg_vpgen_clip_polyline.cpp agg_vpgen_segmentator.cpp - - # src/ctrl - # the following are just GUI controls for the interactive agg demos - #agg_bezier_ctrl.cpp - #agg_cbox_ctrl.cpp - #agg_gamma_ctrl.cpp - #agg_gamma_spline.cpp - #agg_polygon_ctrl.cpp - #agg_rbox_ctrl.cpp - #agg_scale_ctrl.cpp - #agg_slider_ctrl.cpp - #agg_spline_ctrl.cpp - - # gpc - # uncomment this line to enable the General Polygon Clipper - # see the license in gpc.c for usage information - #gpc.c ; -#LinkAgainst libagg.so : root be libfreetype.so ; diff --git a/src/libs/agg/font_freetype/agg_font_freetype.cpp b/src/libs/agg/font_freetype/agg_font_freetype.cpp index 4ec567d488..f94f264378 100644 --- a/src/libs/agg/font_freetype/agg_font_freetype.cpp +++ b/src/libs/agg/font_freetype/agg_font_freetype.cpp @@ -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. @@ -122,31 +122,38 @@ namespace agg return ~crc; } + //------------------------------------------------------------------------ + static inline int dbl_to_plain_fx(double d) + { + return int(d * 65536.0); + } //------------------------------------------------------------------------ - inline double conv_coord_64(int v) + static inline double int26p6_to_dbl(int p) { - return double(v) / 64.0; + return double(p) / 64.0; + } + + //------------------------------------------------------------------------ + static inline int dbl_to_int26p6(double p) + { + return int(p * 64.0 + 0.5); } //------------------------------------------------------------------------ - inline int conv_coord_none(int v) - { - return v; - } - - - //------------------------------------------------------------------------ - template + template bool decompose_ft_outline(const FT_Outline& outline, bool flip_y, - PathStorage& path, - ConvCoord conv) + const trans_affine& mtx, + PathStorage& path) { + typedef typename PathStorage::value_type value_type; + FT_Vector v_last; FT_Vector v_control; FT_Vector v_start; + double x1, y1, x2, y2, x3, y3; FT_Vector* point; FT_Vector* limit; @@ -201,7 +208,12 @@ namespace agg tags--; } - path.move_to(conv(v_start.x), flip_y ? -conv(v_start.y) : conv(v_start.y)); + x1 = int26p6_to_dbl(v_start.x); + y1 = int26p6_to_dbl(v_start.y); + if(flip_y) y1 = -y1; + mtx.transform(&x1, &y1); + path.move_to(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1))); while(point < limit) { @@ -213,7 +225,13 @@ namespace agg { case FT_CURVE_TAG_ON: // emit a single line_to { - path.line_to(conv(point->x), flip_y ? -conv(point->y) : conv(point->y)); + x1 = int26p6_to_dbl(point->x); + y1 = int26p6_to_dbl(point->y); + if(flip_y) y1 = -y1; + mtx.transform(&x1, &y1); + path.line_to(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1))); + //path.line_to(conv(point->x), flip_y ? -conv(point->y) : conv(point->y)); continue; } @@ -237,10 +255,17 @@ namespace agg if(tag == FT_CURVE_TAG_ON) { - path.curve3(conv(v_control.x), - flip_y ? -conv(v_control.y) : conv(v_control.y), - conv(vec.x), - flip_y ? -conv(vec.y) : conv(vec.y)); + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(vec.x); + y2 = int26p6_to_dbl(vec.y); + if(flip_y) { y1 = -y1; y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); continue; } @@ -249,18 +274,43 @@ namespace agg v_middle.x = (v_control.x + vec.x) / 2; v_middle.y = (v_control.y + vec.y) / 2; - path.curve3(conv(v_control.x), - flip_y ? -conv(v_control.y) : conv(v_control.y), - conv(v_middle.x), - flip_y ? -conv(v_middle.y) : conv(v_middle.y)); + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(v_middle.x); + y2 = int26p6_to_dbl(v_middle.y); + if(flip_y) { y1 = -y1; y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); + + //path.curve3(conv(v_control.x), + // flip_y ? -conv(v_control.y) : conv(v_control.y), + // conv(v_middle.x), + // flip_y ? -conv(v_middle.y) : conv(v_middle.y)); v_control = vec; goto Do_Conic; } - path.curve3(conv(v_control.x), - flip_y ? -conv(v_control.y) : conv(v_control.y), - conv(v_start.x), - flip_y ? -conv(v_start.y) : conv(v_start.y)); + + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(v_start.x); + y2 = int26p6_to_dbl(v_start.y); + if(flip_y) { y1 = -y1; y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); + + //path.curve3(conv(v_control.x), + // flip_y ? -conv(v_control.y) : conv(v_control.y), + // conv(v_start.x), + // flip_y ? -conv(v_start.y) : conv(v_start.y)); goto Close; } @@ -288,21 +338,55 @@ namespace agg vec.x = point->x; vec.y = point->y; - path.curve4(conv(vec1.x), - flip_y ? -conv(vec1.y) : conv(vec1.y), - conv(vec2.x), - flip_y ? -conv(vec2.y) : conv(vec2.y), - conv(vec.x), - flip_y ? -conv(vec.y) : conv(vec.y)); + x1 = int26p6_to_dbl(vec1.x); + y1 = int26p6_to_dbl(vec1.y); + x2 = int26p6_to_dbl(vec2.x); + y2 = int26p6_to_dbl(vec2.y); + x3 = int26p6_to_dbl(vec.x); + y3 = int26p6_to_dbl(vec.y); + if(flip_y) { y1 = -y1; y2 = -y2; y3 = -y3; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + mtx.transform(&x3, &y3); + path.curve4(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2)), + value_type(dbl_to_int26p6(x3)), + value_type(dbl_to_int26p6(y3))); + + //path.curve4(conv(vec1.x), + // flip_y ? -conv(vec1.y) : conv(vec1.y), + // conv(vec2.x), + // flip_y ? -conv(vec2.y) : conv(vec2.y), + // conv(vec.x), + // flip_y ? -conv(vec.y) : conv(vec.y)); continue; } - path.curve4(conv(vec1.x), - flip_y ? -conv(vec1.y) : conv(vec1.y), - conv(vec2.x), - flip_y ? -conv(vec2.y) : conv(vec2.y), - conv(v_start.x), - flip_y ? -conv(v_start.y) : conv(v_start.y)); + x1 = int26p6_to_dbl(vec1.x); + y1 = int26p6_to_dbl(vec1.y); + x2 = int26p6_to_dbl(vec2.x); + y2 = int26p6_to_dbl(vec2.y); + x3 = int26p6_to_dbl(v_start.x); + y3 = int26p6_to_dbl(v_start.y); + if(flip_y) { y1 = -y1; y2 = -y2; y3 = -y3; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + mtx.transform(&x3, &y3); + path.curve4(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2)), + value_type(dbl_to_int26p6(x3)), + value_type(dbl_to_int26p6(y3))); + + //path.curve4(conv(vec1.x), + // flip_y ? -conv(vec1.y) : conv(vec1.y), + // conv(vec2.x), + // flip_y ? -conv(vec2.y) : conv(vec2.y), + // conv(v_start.x), + // flip_y ? -conv(v_start.y) : conv(v_start.y)); goto Close; } } @@ -331,7 +415,7 @@ namespace agg const int8u* buf = (const int8u*)bitmap.buffer; int pitch = bitmap.pitch; sl.reset(x, x + bitmap.width); - storage.prepare(bitmap.width + 2); + storage.prepare(); if(flip_y) { buf += bitmap.pitch * (bitmap.rows - 1); @@ -372,7 +456,7 @@ namespace agg const int8u* buf = (const int8u*)bitmap.buffer; int pitch = bitmap.pitch; sl.reset(x, x + bitmap.width); - storage.prepare(bitmap.width + 2); + storage.prepare(); if(flip_y) { buf += bitmap.pitch * (bitmap.rows - 1); @@ -466,10 +550,6 @@ namespace agg m_scanlines_bin(), m_rasterizer() { - m_matrix.xx = 0x10000L; - m_matrix.xy = 0; - m_matrix.yx = 0; - m_matrix.yy = 0x10000L; m_curves16.approximation_scale(4.0); m_curves32.approximation_scale(4.0); m_last_error = FT_Init_FreeType(&m_library); @@ -498,10 +578,33 @@ namespace agg } + //------------------------------------------------------------------------ + double font_engine_freetype_base::ascender() const + { + if(m_cur_face) + { + return m_cur_face->ascender * height() / m_cur_face->height; + } + return 0.0; + } + + //------------------------------------------------------------------------ + double font_engine_freetype_base::descender() const + { + if(m_cur_face) + { + return m_cur_face->descender * height() / m_cur_face->height; + } + return 0.0; + } + + //------------------------------------------------------------------------ bool font_engine_freetype_base::load_font(const char* font_name, unsigned face_index, - glyph_rendering ren_type) + glyph_rendering ren_type, + const char* font_mem, + const long font_mem_size) { bool ret = false; @@ -530,10 +633,22 @@ namespace agg m_num_faces = m_max_faces - 1; } - m_last_error = FT_New_Face(m_library, - font_name, - face_index, - &m_faces[m_num_faces]); + if (font_mem && font_mem_size) + { + m_last_error = FT_New_Memory_Face(m_library, + (const FT_Byte*)font_mem, + font_mem_size, + face_index, + &m_faces[m_num_faces]); + } + else + { + m_last_error = FT_New_Face(m_library, + font_name, + face_index, + &m_faces[m_num_faces]); + } + if(m_last_error == 0) { m_face_names[m_num_faces] = new char [strlen(font_name) + 1]; @@ -554,7 +669,7 @@ namespace agg if(m_last_error == 0) { ret = true; - + switch(ren_type) { case glyph_ren_native_mono: @@ -598,8 +713,7 @@ namespace agg } break; } - - update_transform(); + update_signature(); } } return ret; @@ -666,55 +780,6 @@ namespace agg return false; } - - //------------------------------------------------------------------------ - void font_engine_freetype_base::update_transform() - { - FT_Matrix mtx = m_matrix; - - if(m_flip_y) - { - mtx.xy = -mtx.xy; - mtx.yy = -mtx.yy; - } - - if(m_cur_face) - { - FT_Vector pen; - pen.x = 0; - pen.y = 0; - FT_Set_Transform(m_cur_face, &mtx, &pen); - update_signature(); - } - } - - - //------------------------------------------------------------------------ - void font_engine_freetype_base::transform(const trans_affine& mtx) - { - double m[6]; - mtx.store_to(m); - - m_matrix.xx = long( m[0] * 0x10000L); - m_matrix.xy = long(-m[1] * 0x10000L); - m_matrix.yx = long(-m[2] * 0x10000L); - m_matrix.yy = long( m[3] * 0x10000L); - update_transform(); - } - - - //------------------------------------------------------------------------ - void font_engine_freetype_base::transform(double xx, double xy, - double yx, double yy) - { - m_matrix.xx = long( xx * 0x10000L); - m_matrix.xy = long(-xy * 0x10000L); - m_matrix.yx = long(-yx * 0x10000L); - m_matrix.yy = long( yy * 0x10000L); - update_transform(); - } - - //------------------------------------------------------------------------ void font_engine_freetype_base::hinting(bool h) { @@ -731,7 +796,17 @@ namespace agg m_flip_y = f; if(m_cur_face) { - update_transform(); + update_signature(); + } + } + + //------------------------------------------------------------------------ + void font_engine_freetype_base::transform(const trans_affine& affine) + { + m_affine = affine; + if(m_cur_face) + { + update_signature(); } } @@ -753,9 +828,9 @@ namespace agg m_glyph_rendering == glyph_ren_agg_mono || m_glyph_rendering == glyph_ren_agg_gray8) { - unsigned char gamma_table[rasterizer_scanline_aa<>::aa_num]; + unsigned char gamma_table[rasterizer_scanline_aa<>::aa_scale]; unsigned i; - for(i = 0; i < rasterizer_scanline_aa<>::aa_num; ++i) + for(i = 0; i < rasterizer_scanline_aa<>::aa_scale; ++i) { gamma_table[i] = m_rasterizer.apply_gamma(i); } @@ -763,7 +838,7 @@ namespace agg } sprintf(m_signature, - "%s,%u,%d,%d,%d:%dx%d,%d,%d,%d,%d,%d,%d,%08X", + "%s,%u,%d,%d,%d:%dx%d,%d,%d,%08X", m_name, m_char_map, m_face_index, @@ -771,13 +846,25 @@ namespace agg m_resolution, m_height, m_width, - int(m_matrix.xx), - int(m_matrix.xy), - int(m_matrix.yx), - int(m_matrix.yy), int(m_hinting), int(m_flip_y), gamma_hash); + if(m_glyph_rendering == glyph_ren_outline || + m_glyph_rendering == glyph_ren_agg_mono || + m_glyph_rendering == glyph_ren_agg_gray8) + { + double mtx[6]; + char buf[100]; + m_affine.store_to(mtx); + sprintf(buf, ",%08X%08X%08X%08X%08X%08X", + dbl_to_plain_fx(mtx[0]), + dbl_to_plain_fx(mtx[1]), + dbl_to_plain_fx(mtx[2]), + dbl_to_plain_fx(mtx[3]), + dbl_to_plain_fx(mtx[4]), + dbl_to_plain_fx(mtx[5])); + strcat(m_signature, buf); + } ++m_change_stamp; } } @@ -813,9 +900,6 @@ namespace agg //------------------------------------------------------------------------ bool font_engine_freetype_base::prepare_glyph(unsigned glyph_code) { - bool flip = false; - - m_glyph_index = FT_Get_Char_Index(m_cur_face, glyph_code); m_last_error = FT_Load_Glyph(m_cur_face, m_glyph_index, @@ -827,24 +911,23 @@ namespace agg { case glyph_ren_native_mono: m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_MONO); -//printf("%i\n", m_last_error); if(m_last_error == 0) { decompose_ft_bitmap_mono(m_cur_face->glyph->bitmap, m_cur_face->glyph->bitmap_left, - flip ? -m_cur_face->glyph->bitmap_top : - m_cur_face->glyph->bitmap_top, - flip, + m_flip_y ? -m_cur_face->glyph->bitmap_top : + m_cur_face->glyph->bitmap_top, + m_flip_y, m_scanline_bin, m_scanlines_bin); m_bounds.x1 = m_scanlines_bin.min_x(); m_bounds.y1 = m_scanlines_bin.min_y(); - m_bounds.x2 = m_scanlines_bin.max_x(); - m_bounds.y2 = m_scanlines_bin.max_y(); + m_bounds.x2 = m_scanlines_bin.max_x() + 1; + m_bounds.y2 = m_scanlines_bin.max_y() + 1; m_data_size = m_scanlines_bin.byte_size(); m_data_type = glyph_data_mono; - m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; - m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); return true; } break; @@ -856,20 +939,20 @@ namespace agg { decompose_ft_bitmap_gray8(m_cur_face->glyph->bitmap, m_cur_face->glyph->bitmap_left, - flip ? -m_cur_face->glyph->bitmap_top : - m_cur_face->glyph->bitmap_top, - flip, + m_flip_y ? -m_cur_face->glyph->bitmap_top : + m_cur_face->glyph->bitmap_top, + m_flip_y, m_rasterizer, m_scanline_aa, m_scanlines_aa); m_bounds.x1 = m_scanlines_aa.min_x(); m_bounds.y1 = m_scanlines_aa.min_y(); - m_bounds.x2 = m_scanlines_aa.max_x(); - m_bounds.y2 = m_scanlines_aa.max_y(); + m_bounds.x2 = m_scanlines_aa.max_x() + 1; + m_bounds.y2 = m_scanlines_aa.max_y() + 1; m_data_size = m_scanlines_aa.byte_size(); m_data_type = glyph_data_gray8; - m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; - m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); return true; } break; @@ -882,9 +965,9 @@ namespace agg { m_path32.remove_all(); if(decompose_ft_outline(m_cur_face->glyph->outline, - flip, - m_path32, - conv_coord_none)) + m_flip_y, + m_affine, + m_path32)) { rect_d bnd = m_path32.bounding_rect(); m_data_size = m_path32.byte_size(); @@ -893,8 +976,9 @@ namespace agg m_bounds.y1 = int(floor(bnd.y1)); m_bounds.x2 = int(ceil(bnd.x2)); m_bounds.y2 = int(ceil(bnd.y2)); - m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; - m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + m_affine.transform(&m_advance_x, &m_advance_y); return true; } } @@ -902,9 +986,9 @@ namespace agg { m_path16.remove_all(); if(decompose_ft_outline(m_cur_face->glyph->outline, - flip, - m_path16, - conv_coord_none)) + m_flip_y, + m_affine, + m_path16)) { rect_d bnd = m_path16.bounding_rect(); m_data_size = m_path16.byte_size(); @@ -913,8 +997,9 @@ namespace agg m_bounds.y1 = int(floor(bnd.y1)); m_bounds.x2 = int(ceil(bnd.x2)); m_bounds.y2 = int(ceil(bnd.y2)); - m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; - m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + m_affine.transform(&m_advance_x, &m_advance_y); return true; } } @@ -929,30 +1014,31 @@ namespace agg { m_path32.remove_all(); decompose_ft_outline(m_cur_face->glyph->outline, - flip, - m_path32, - conv_coord_none); + m_flip_y, + m_affine, + m_path32); m_rasterizer.add_path(m_curves32); } else { m_path16.remove_all(); decompose_ft_outline(m_cur_face->glyph->outline, - flip, - m_path16, - conv_coord_none); + m_flip_y, + m_affine, + m_path16); m_rasterizer.add_path(m_curves16); } - m_scanlines_bin.prepare(1); // Remove all + m_scanlines_bin.prepare(); // Remove all render_scanlines(m_rasterizer, m_scanline_bin, m_scanlines_bin); m_bounds.x1 = m_scanlines_bin.min_x(); m_bounds.y1 = m_scanlines_bin.min_y(); - m_bounds.x2 = m_scanlines_bin.max_x(); - m_bounds.y2 = m_scanlines_bin.max_y(); + m_bounds.x2 = m_scanlines_bin.max_x() + 1; + m_bounds.y2 = m_scanlines_bin.max_y() + 1; m_data_size = m_scanlines_bin.byte_size(); m_data_type = glyph_data_mono; - m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; - m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + m_affine.transform(&m_advance_x, &m_advance_y); return true; } return false; @@ -966,30 +1052,31 @@ namespace agg { m_path32.remove_all(); decompose_ft_outline(m_cur_face->glyph->outline, - flip, - m_path32, - conv_coord_none); + m_flip_y, + m_affine, + m_path32); m_rasterizer.add_path(m_curves32); } else { m_path16.remove_all(); decompose_ft_outline(m_cur_face->glyph->outline, - flip, - m_path16, - conv_coord_none); + m_flip_y, + m_affine, + m_path16); m_rasterizer.add_path(m_curves16); } - m_scanlines_aa.prepare(1); // Remove all + m_scanlines_aa.prepare(); // Remove all render_scanlines(m_rasterizer, m_scanline_aa, m_scanlines_aa); m_bounds.x1 = m_scanlines_aa.min_x(); m_bounds.y1 = m_scanlines_aa.min_y(); - m_bounds.x2 = m_scanlines_aa.max_x(); - m_bounds.y2 = m_scanlines_aa.max_y(); + m_bounds.x2 = m_scanlines_aa.max_x() + 1; + m_bounds.y2 = m_scanlines_aa.max_y() + 1; m_data_size = m_scanlines_aa.byte_size(); m_data_type = glyph_data_gray8; - m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; - m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + m_affine.transform(&m_advance_x, &m_advance_y); return true; } return false; @@ -1037,9 +1124,17 @@ namespace agg FT_Vector delta; FT_Get_Kerning(m_cur_face, first, second, FT_KERNING_DEFAULT, &delta); - FT_Vector_Transform(&delta, &m_matrix); - *x += double(delta.x) / 64.0; - *y += double(delta.y) / 64.0; + double dx = int26p6_to_dbl(delta.x); + double dy = int26p6_to_dbl(delta.y); + if(m_glyph_rendering == glyph_ren_outline || + m_glyph_rendering == glyph_ren_agg_mono || + m_glyph_rendering == glyph_ren_agg_gray8) + { + m_affine.transform_2x2(&dx, &dy); + } + *x += dx; + *y += dy; + return true; } return false; diff --git a/src/libs/agg/font_freetype/agg_font_freetype.h b/src/libs/agg/font_freetype/agg_font_freetype.h index 095bd4a59b..273243c334 100644 --- a/src/libs/agg/font_freetype/agg_font_freetype.h +++ b/src/libs/agg/font_freetype/agg_font_freetype.h @@ -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. @@ -31,8 +31,8 @@ #include "agg_path_storage_integer.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_conv_curve.h" -#include "agg_trans_affine.h" #include "agg_font_cache_manager.h" +#include "agg_trans_affine.h" namespace agg { @@ -55,15 +55,15 @@ namespace agg // Set font parameters //-------------------------------------------------------------------- void resolution(unsigned dpi); - bool load_font(const char* font_name, unsigned face_index, glyph_rendering ren_type); + bool load_font(const char* font_name, unsigned face_index, glyph_rendering ren_type, + const char* font_mem = 0, const long font_mem_size = 0); bool attach(const char* file_name); bool char_map(FT_Encoding map); bool height(double h); bool width(double w); - void transform(const trans_affine& mtx); - void transform(double xx, double xy, double yx, double yy); void hinting(bool h); void flip_y(bool f); + void transform(const trans_affine& affine); // Set Gamma //-------------------------------------------------------------------- @@ -79,8 +79,10 @@ namespace agg const char* name() const { return m_name; } unsigned num_faces() const; FT_Encoding char_map() const { return m_char_map; } - double height() const { return double(m_height) / 64.0; } - double width() const { return double(m_width) / 64.0; } + double height() const { return double(m_height) / 64.0; } + double width() const { return double(m_width) / 64.0; } + double ascender() const; + double descender() const; bool hinting() const { return m_hinting; } bool flip_y() const { return m_flip_y; } @@ -94,7 +96,7 @@ namespace agg unsigned glyph_index() const { return m_glyph_index; } unsigned data_size() const { return m_data_size; } glyph_data_type data_type() const { return m_data_type; } - const rect& bounds() const { return m_bounds; } + const rect_i& bounds() const { return m_bounds; } double advance_x() const { return m_advance_x; } double advance_y() const { return m_advance_y; } void write_glyph_to(int8u* data) const; @@ -107,7 +109,6 @@ namespace agg void update_char_size(); void update_signature(); - void update_transform(); int find_face(const char* face_name) const; bool m_flag32; @@ -120,7 +121,6 @@ namespace agg char* m_signature; unsigned m_height; unsigned m_width; - FT_Matrix m_matrix; bool m_hinting; bool m_flip_y; bool m_library_initialized; @@ -135,9 +135,10 @@ namespace agg unsigned m_glyph_index; unsigned m_data_size; glyph_data_type m_data_type; - rect m_bounds; + rect_i m_bounds; double m_advance_x; double m_advance_y; + trans_affine m_affine; path_storage_integer m_path16; path_storage_integer m_path32; diff --git a/src/libs/agg/gpc/gpc.c b/src/libs/agg/gpc/gpc.c index 61edc2d248..b9cce1bed2 100644 --- a/src/libs/agg/gpc/gpc.c +++ b/src/libs/agg/gpc/gpc.c @@ -8,10 +8,10 @@ Project: Generic Polygon Clipper File: gpc.c Author: Alan Murta (email: gpc@cs.man.ac.uk) -Version: 2.31 -Date: 4th June 1999 +Version: 2.32 +Date: 17th December 2004 -Copyright: (C) 1997-1999, Advanced Interfaces Group, +Copyright: (C) 1997-2004, Advanced Interfaces Group, University of Manchester. This software is free for non-commercial use. It may be copied, @@ -101,10 +101,10 @@ Copyright: (C) 1997-1999, Advanced Interfaces Group, do {(d)= (d)->next;} while (!(d)->outp[(p)]); \ (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);} -#define MALLOC(p, b, s) {if ((b) > 0) { \ - p= malloc(b); if (!(p)) { \ +#define MALLOC(p, b, s, t) {if ((b) > 0) { \ + p= (t*)malloc(b); if (!(p)) { \ fprintf(stderr, "gpc malloc failure: %s\n", s); \ - exit(0);}} else p= NULL;} + exit(0);}} else p= NULL;} #define FREE(p) {if (p) {free(p); (p)= NULL;}} @@ -327,7 +327,7 @@ static edge_node **bound_list(lmt_node **lmt, double y) if (!*lmt) { /* Add node onto the tail end of the LMT */ - MALLOC(*lmt, sizeof(lmt_node), "LMT insertion"); + MALLOC(*lmt, sizeof(lmt_node), "LMT insertion", lmt_node); (*lmt)->y= y; (*lmt)->first_bound= NULL; (*lmt)->next= NULL; @@ -338,7 +338,7 @@ static edge_node **bound_list(lmt_node **lmt, double y) { /* Insert a new LMT node before the current node */ existing_node= *lmt; - MALLOC(*lmt, sizeof(lmt_node), "LMT insertion"); + MALLOC(*lmt, sizeof(lmt_node), "LMT insertion", lmt_node); (*lmt)->y= y; (*lmt)->first_bound= NULL; (*lmt)->next= existing_node; @@ -359,7 +359,7 @@ static void add_to_sbtree(int *entries, sb_tree **sbtree, double y) if (!*sbtree) { /* Add a new tree node here */ - MALLOC(*sbtree, sizeof(sb_tree), "scanbeam tree insertion"); + MALLOC(*sbtree, sizeof(sb_tree), "scanbeam tree insertion", sb_tree); (*sbtree)->y= y; (*sbtree)->less= NULL; (*sbtree)->more= NULL; @@ -435,7 +435,7 @@ static edge_node *build_lmt(lmt_node **lmt, sb_tree **sbtree, /* Create the entire input polygon edge table in one go */ MALLOC(edge_table, total_vertices * sizeof(edge_node), - "edge table creation"); + "edge table creation", edge_node); for (c= 0; c < p->num_contours; c++) { @@ -623,7 +623,7 @@ static void add_intersection(it_node **it, edge_node *edge0, edge_node *edge1, if (!*it) { /* Append a new node to the tail of the list */ - MALLOC(*it, sizeof(it_node), "IT insertion"); + MALLOC(*it, sizeof(it_node), "IT insertion", it_node); (*it)->ie[0]= edge0; (*it)->ie[1]= edge1; (*it)->point.x= x; @@ -636,7 +636,7 @@ static void add_intersection(it_node **it, edge_node *edge0, edge_node *edge1, { /* Insert a new node mid-list */ existing_node= *it; - MALLOC(*it, sizeof(it_node), "IT insertion"); + MALLOC(*it, sizeof(it_node), "IT insertion", it_node); (*it)->ie[0]= edge0; (*it)->ie[1]= edge1; (*it)->point.x= x; @@ -659,7 +659,7 @@ static void add_st_edge(st_node **st, it_node **it, edge_node *edge, if (!*st) { /* Append edge onto the tail end of the ST */ - MALLOC(*st, sizeof(st_node), "ST insertion"); + MALLOC(*st, sizeof(st_node), "ST insertion", st_node); (*st)->edge= edge; (*st)->xb= edge->xb; (*st)->xt= edge->xt; @@ -676,7 +676,7 @@ static void add_st_edge(st_node **st, it_node **it, edge_node *edge, { /* No intersection - insert edge here (before the ST edge) */ existing_node= *st; - MALLOC(*st, sizeof(st_node), "ST insertion"); + MALLOC(*st, sizeof(st_node), "ST insertion", st_node); (*st)->edge= edge; (*st)->xb= edge->xb; (*st)->xt= edge->xt; @@ -765,7 +765,7 @@ static void add_left(polygon_node *p, double x, double y) vertex_node *nv; /* Create a new vertex node and set its fields */ - MALLOC(nv, sizeof(vertex_node), "vertex node creation"); + MALLOC(nv, sizeof(vertex_node), "vertex node creation", vertex_node); nv->x= x; nv->y= y; @@ -809,7 +809,7 @@ static void add_right(polygon_node *p, double x, double y) vertex_node *nv; /* Create a new vertex node and set its fields */ - MALLOC(nv, sizeof(vertex_node), "vertex node creation"); + MALLOC(nv, sizeof(vertex_node), "vertex node creation", vertex_node); nv->x= x; nv->y= y; nv->next= NULL; @@ -856,10 +856,10 @@ static void add_local_min(polygon_node **p, edge_node *edge, existing_min= *p; - MALLOC(*p, sizeof(polygon_node), "polygon node creation"); + MALLOC(*p, sizeof(polygon_node), "polygon node creation", polygon_node); /* Create a new vertex node and set its fields */ - MALLOC(nv, sizeof(vertex_node), "vertex node creation"); + MALLOC(nv, sizeof(vertex_node), "vertex node creation", vertex_node); nv->x= x; nv->y= y; nv->next= NULL; @@ -893,7 +893,7 @@ static void add_vertex(vertex_node **t, double x, double y) { if (!(*t)) { - MALLOC(*t, sizeof(vertex_node), "tristrip vertex creation"); + MALLOC(*t, sizeof(vertex_node), "tristrip vertex creation", vertex_node); (*t)->x= x; (*t)->y= y; (*t)->next= NULL; @@ -909,7 +909,7 @@ static void new_tristrip(polygon_node **tn, edge_node *edge, { if (!(*tn)) { - MALLOC(*tn, sizeof(polygon_node), "tristrip node creation"); + MALLOC(*tn, sizeof(polygon_node), "tristrip node creation", polygon_node); (*tn)->next= NULL; (*tn)->v[LEFT]= NULL; (*tn)->v[RIGHT]= NULL; @@ -928,7 +928,7 @@ static bbox *create_contour_bboxes(gpc_polygon *p) bbox *box; int c, v; - MALLOC(box, p->num_contours * sizeof(bbox), "Bounding box creation"); + MALLOC(box, p->num_contours * sizeof(bbox), "Bounding box creation", bbox); /* Construct contour bounding boxes */ for (c= 0; c < p->num_contours; c++) @@ -965,7 +965,7 @@ static void minimax_test(gpc_polygon *subj, gpc_polygon *clip, gpc_op op) c_bbox= create_contour_bboxes(clip); MALLOC(o_table, subj->num_contours * clip->num_contours * sizeof(int), - "overlap table creation"); + "overlap table creation", int); /* Check all subject contour bounding boxes against clip boxes */ for (s= 0; s < subj->num_contours; s++) @@ -1033,9 +1033,9 @@ void gpc_read_polygon(FILE *fp, int read_hole_flags, gpc_polygon *p) fscanf(fp, "%d", &(p->num_contours)); MALLOC(p->hole, p->num_contours * sizeof(int), - "hole flag array creation"); + "hole flag array creation", int); MALLOC(p->contour, p->num_contours - * sizeof(gpc_vertex_list), "contour creation"); + * sizeof(gpc_vertex_list), "contour creation", gpc_vertex_list); for (c= 0; c < p->num_contours; c++) { fscanf(fp, "%d", &(p->contour[c].num_vertices)); @@ -1046,7 +1046,7 @@ void gpc_read_polygon(FILE *fp, int read_hole_flags, gpc_polygon *p) p->hole[c]= FALSE; /* Assume all contours to be external */ MALLOC(p->contour[c].vertex, p->contour[c].num_vertices - * sizeof(gpc_vertex), "vertex creation"); + * sizeof(gpc_vertex), "vertex creation", gpc_vertex); for (v= 0; v < p->contour[c].num_vertices; v++) fscanf(fp, "%lf %lf", &(p->contour[c].vertex[v].x), &(p->contour[c].vertex[v].y)); @@ -1081,11 +1081,11 @@ void gpc_add_contour(gpc_polygon *p, gpc_vertex_list *new_contour, int hole) /* Create an extended hole array */ MALLOC(extended_hole, (p->num_contours + 1) - * sizeof(int), "contour hole addition"); + * sizeof(int), "contour hole addition", int); /* Create an extended contour array */ MALLOC(extended_contour, (p->num_contours + 1) - * sizeof(gpc_vertex_list), "contour addition"); + * sizeof(gpc_vertex_list), "contour addition", gpc_vertex_list); /* Copy the old contour and hole data into the extended arrays */ for (c= 0; c < p->num_contours; c++) @@ -1099,7 +1099,7 @@ void gpc_add_contour(gpc_polygon *p, gpc_vertex_list *new_contour, int hole) extended_hole[c]= hole; extended_contour[c].num_vertices= new_contour->num_vertices; MALLOC(extended_contour[c].vertex, new_contour->num_vertices - * sizeof(gpc_vertex), "contour addition"); + * sizeof(gpc_vertex), "contour addition", gpc_vertex); for (v= 0; v < new_contour->num_vertices; v++) extended_contour[c].vertex[v]= new_contour->vertex[v]; @@ -1165,7 +1165,7 @@ void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, } /* Build scanbeam table from scanbeam tree */ - MALLOC(sbt, sbt_entries * sizeof(double), "sbt creation"); + MALLOC(sbt, sbt_entries * sizeof(double), "sbt creation", double); build_sbt(&scanbeam, sbt, sbtree); scanbeam= 0; free_sbtree(&sbtree); @@ -1691,7 +1691,7 @@ void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP]; edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ]; edge->xb= edge->xt; - } + } edge->outp[ABOVE]= NULL; } } @@ -1704,9 +1704,9 @@ void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, if (result->num_contours > 0) { MALLOC(result->hole, result->num_contours - * sizeof(int), "hole flag table creation"); + * sizeof(int), "hole flag table creation", int); MALLOC(result->contour, result->num_contours - * sizeof(gpc_vertex_list), "contour creation"); + * sizeof(gpc_vertex_list), "contour creation", gpc_vertex_list); c= 0; for (poly= out_poly; poly; poly= npoly) @@ -1718,7 +1718,7 @@ void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, result->contour[c].num_vertices= poly->active; MALLOC(result->contour[c].vertex, result->contour[c].num_vertices * sizeof(gpc_vertex), - "vertex creation"); + "vertex creation", gpc_vertex); v= result->contour[c].num_vertices - 1; for (vtx= poly->proxy->v[LEFT]; vtx; vtx= nv) @@ -1734,6 +1734,14 @@ void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, FREE(poly); } } + else + { + for (poly= out_poly; poly; poly= npoly) + { + npoly= poly->next; + FREE(poly); + } + } /* Tidy up */ reset_it(&it); @@ -1816,7 +1824,7 @@ void gpc_tristrip_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, } /* Build scanbeam table from scanbeam tree */ - MALLOC(sbt, sbt_entries * sizeof(double), "sbt creation"); + MALLOC(sbt, sbt_entries * sizeof(double), "sbt creation", double); build_sbt(&scanbeam, sbt, sbtree); scanbeam= 0; free_sbtree(&sbtree); @@ -2384,7 +2392,7 @@ void gpc_tristrip_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, if (result->num_strips > 0) { MALLOC(result->strip, result->num_strips * sizeof(gpc_vertex_list), - "tristrip list creation"); + "tristrip list creation", gpc_vertex_list); s= 0; for (tn= tlist; tn; tn= tnn) @@ -2396,7 +2404,7 @@ void gpc_tristrip_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, /* Valid tristrip: copy the vertices and free the heap */ result->strip[s].num_vertices= tn->active; MALLOC(result->strip[s].vertex, tn->active * sizeof(gpc_vertex), - "tristrip creation"); + "tristrip creation", gpc_vertex); v= 0; if (INVERT_TRISTRIPS) { diff --git a/src/libs/agg/gpc/gpc.h b/src/libs/agg/gpc/gpc.h index 98aa6fa2d7..ff00f7b6c2 100644 --- a/src/libs/agg/gpc/gpc.h +++ b/src/libs/agg/gpc/gpc.h @@ -8,10 +8,10 @@ Project: Generic Polygon Clipper File: gpc.h Author: Alan Murta (email: gpc@cs.man.ac.uk) -Version: 2.31 -Date: 4th June 1999 +Version: 2.32 +Date: 17th December 2004 -Copyright: (C) 1997-1999, Advanced Interfaces Group, +Copyright: (C) 1997-2004, Advanced Interfaces Group, University of Manchester. This software is free for non-commercial use. It may be copied, @@ -46,7 +46,7 @@ Copyright: (C) 1997-1999, Advanced Interfaces Group, #define GPC_EPSILON (DBL_EPSILON) -#define GPC_VERSION "2.31" +#define GPC_VERSION "2.32" /* diff --git a/src/libs/agg/src/agg_arc.cpp b/src/libs/agg/src/agg_arc.cpp index a6f32a556b..df2c43a559 100644 --- a/src/libs/agg/src/agg_arc.cpp +++ b/src/libs/agg/src/agg_arc.cpp @@ -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,7 +65,7 @@ namespace agg unsigned arc::vertex(double* x, double* y) { if(is_stop(m_path_cmd)) return path_cmd_stop; - if((m_angle < m_end) != m_ccw) + if((m_angle < m_end - m_da/4) != m_ccw) { *x = m_x + cos(m_end) * m_rx; *y = m_y + sin(m_end) * m_ry; @@ -86,7 +86,8 @@ namespace agg //------------------------------------------------------------------------ void arc::normalize(double a1, double a2, bool ccw) { - m_da = fabs(1.0 / ((m_rx + m_ry) * 0.5 * m_scale)); + double ra = (fabs(m_rx) + fabs(m_ry)) / 2; + m_da = acos(ra / (ra + 0.125 / m_scale)) * 2; if(ccw) { while(a2 < a1) a2 += pi * 2.0; diff --git a/src/libs/agg/src/agg_arrowhead.cpp b/src/libs/agg/src/agg_arrowhead.cpp index 7b731bdd06..1a6f8b4100 100644 --- a/src/libs/agg/src/agg_arrowhead.cpp +++ b/src/libs/agg/src/agg_arrowhead.cpp @@ -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. @@ -42,11 +42,11 @@ namespace agg //------------------------------------------------------------------------ - void arrowhead::rewind(unsigned id) + void arrowhead::rewind(unsigned path_id) { - m_curr_id = id; + m_curr_id = path_id; m_curr_coord = 0; - if(id == 0) + if(path_id == 0) { if(!m_tail_flag) { @@ -71,7 +71,7 @@ namespace agg return; } - if(id == 1) + if(path_id == 1) { if(!m_head_flag) { diff --git a/src/libs/agg/src/agg_bezier_arc.cpp b/src/libs/agg/src/agg_bezier_arc.cpp index 4a996aa647..844d300c09 100644 --- a/src/libs/agg/src/agg_bezier_arc.cpp +++ b/src/libs/agg/src/agg_bezier_arc.cpp @@ -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. @@ -26,6 +26,14 @@ namespace agg { + // This epsilon is used to prevent us from adding degenerate curves + // (converging to a single point). + // The value isn't very critical. Function arc_to_bezier() has a limit + // of the sweep_angle. If fabs(sweep_angle) exceeds pi/2 the curve + // becomes inaccurate. But slight exceeding is quite appropriate. + //-------------------------------------------------bezier_arc_angle_epsilon + const double bezier_arc_angle_epsilon = 0.01; + //------------------------------------------------------------arc_to_bezier void arc_to_bezier(double cx, double cy, double rx, double ry, double start_angle, double sweep_angle, @@ -69,29 +77,44 @@ namespace agg if(sweep_angle >= 2.0 * pi) sweep_angle = 2.0 * pi; if(sweep_angle <= -2.0 * pi) sweep_angle = -2.0 * pi; + if(fabs(sweep_angle) < 1e-10) + { + m_num_vertices = 4; + m_cmd = path_cmd_line_to; + m_vertices[0] = x + rx * cos(start_angle); + m_vertices[1] = y + ry * sin(start_angle); + m_vertices[2] = x + rx * cos(start_angle + sweep_angle); + m_vertices[3] = y + ry * sin(start_angle + sweep_angle); + return; + } + double total_sweep = 0.0; double local_sweep = 0.0; + double prev_sweep; m_num_vertices = 2; + m_cmd = path_cmd_curve4; bool done = false; do { if(sweep_angle < 0.0) { + prev_sweep = total_sweep; local_sweep = -pi * 0.5; total_sweep -= pi * 0.5; - if(total_sweep <= sweep_angle) + if(total_sweep <= sweep_angle + bezier_arc_angle_epsilon) { - local_sweep = sweep_angle - (total_sweep + pi * 0.5); + local_sweep = sweep_angle - prev_sweep; done = true; } } else { + prev_sweep = total_sweep; local_sweep = pi * 0.5; total_sweep += pi * 0.5; - if(total_sweep >= sweep_angle) + if(total_sweep >= sweep_angle - bezier_arc_angle_epsilon) { - local_sweep = sweep_angle - (total_sweep - pi * 0.5); + local_sweep = sweep_angle - prev_sweep; done = true; } } @@ -129,8 +152,6 @@ namespace agg double dx2 = (x0 - x2) / 2.0; double dy2 = (y0 - y2) / 2.0; - // Convert angle from degrees to radians - //------------------------ double cos_a = cos(angle); double sin_a = sin(angle); diff --git a/src/libs/agg/src/agg_bspline.cpp b/src/libs/agg/src/agg_bspline.cpp index 6bd67d2fc2..e1fda9f51f 100644 --- a/src/libs/agg/src/agg_bspline.cpp +++ b/src/libs/agg/src/agg_bspline.cpp @@ -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,26 +17,16 @@ // //---------------------------------------------------------------------------- - #include "agg_bspline.h" namespace agg { - - //------------------------------------------------------------------------ - bspline::~bspline() - { - delete [] m_am; - } - - //------------------------------------------------------------------------ bspline::bspline() : m_max(0), m_num(0), m_x(0), m_y(0), - m_am(0), m_last_idx(-1) { } @@ -47,7 +37,6 @@ namespace agg m_num(0), m_x(0), m_y(0), - m_am(0), m_last_idx(-1) { init(num); @@ -59,7 +48,6 @@ namespace agg m_num(0), m_x(0), m_y(0), - m_am(0), m_last_idx(-1) { init(num, x, y); @@ -71,11 +59,10 @@ namespace agg { if(max > 2 && max > m_max) { - delete [] m_am; - m_am = new double[max * 3]; + m_am.resize(max * 3); m_max = max; - m_x = m_am + m_max; - m_y = m_am + m_max * 2; + m_x = &m_am[m_max]; + m_y = &m_am[m_max * 2]; } m_num = 0; m_last_idx = -1; @@ -103,7 +90,6 @@ namespace agg double* temp; double* r; double* s; - double* al; double h, p, d, f, e; for(k = 0; k < m_num; k++) @@ -113,8 +99,8 @@ namespace agg n1 = 3 * m_num; - al = new double[n1]; - temp = al; + pod_array al(n1); + temp = &al[0]; for(k = 0; k < n1; k++) { @@ -155,7 +141,6 @@ namespace agg al[k] = al[k] * al[k + 1] + s[k]; m_am[k] = al[k]; } - delete al; } m_last_idx = -1; } diff --git a/src/libs/agg/src/agg_curves.cpp b/src/libs/agg/src/agg_curves.cpp index 710ea17529..cb7a8d7ae2 100644 --- a/src/libs/agg/src/agg_curves.cpp +++ b/src/libs/agg/src/agg_curves.cpp @@ -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,21 +12,38 @@ // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- -// -// classes curve3 and curve4 -// -//---------------------------------------------------------------------------- #include #include "agg_curves.h" +#include "agg_math.h" namespace agg { //------------------------------------------------------------------------ - void curve3::init(double x1, double y1, - double x2, double y2, - double x3, double y3) + const double curve_distance_epsilon = 1e-30; + const double curve_collinearity_epsilon = 1e-30; + const double curve_angle_tolerance_epsilon = 0.01; + enum curve_recursion_limit_e { curve_recursion_limit = 32 }; + + + + //------------------------------------------------------------------------ + void curve3_inc::approximation_scale(double s) + { + m_scale = s; + } + + //------------------------------------------------------------------------ + double curve3_inc::approximation_scale() const + { + return m_scale; + } + + //------------------------------------------------------------------------ + void curve3_inc::init(double x1, double y1, + double x2, double y2, + double x3, double y3) { m_start_x = x1; m_start_y = y1; @@ -40,11 +57,11 @@ namespace agg double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2); - m_num_steps = int(len * 0.25 * m_scale); + m_num_steps = uround(len * 0.25 * m_scale); - if(m_num_steps < 2) + if(m_num_steps < 4) { - m_num_steps = 2; + m_num_steps = 4; } double subdivide_step = 1.0 / m_num_steps; @@ -65,11 +82,8 @@ namespace agg m_step = m_num_steps; } - - - //------------------------------------------------------------------------ - void curve3::rewind(unsigned) + void curve3_inc::rewind(unsigned) { if(m_num_steps == 0) { @@ -83,11 +97,8 @@ namespace agg m_dfy = m_saved_dfy; } - - - //------------------------------------------------------------------------ - unsigned curve3::vertex(double* x, double* y) + unsigned curve3_inc::vertex(double* x, double* y) { if(m_step < 0) return path_cmd_stop; if(m_step == m_num_steps) @@ -114,23 +125,141 @@ namespace agg return path_cmd_line_to; } + //------------------------------------------------------------------------ + void curve3_div::init(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_points.remove_all(); + m_distance_tolerance_square = 0.5 / m_approximation_scale; + m_distance_tolerance_square *= m_distance_tolerance_square; + bezier(x1, y1, x2, y2, x3, y3); + m_count = 0; + } + //------------------------------------------------------------------------ + void curve3_div::recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + unsigned level) + { + if(level > curve_recursion_limit) + { + return; + } + // Calculate all the mid-points of the line segments + //---------------------- + double x12 = (x1 + x2) / 2; + double y12 = (y1 + y2) / 2; + double x23 = (x2 + x3) / 2; + double y23 = (y2 + y3) / 2; + double x123 = (x12 + x23) / 2; + double y123 = (y12 + y23) / 2; + double dx = x3-x1; + double dy = y3-y1; + double d = fabs(((x2 - x3) * dy - (y2 - y3) * dx)); + double da; + if(d > curve_collinearity_epsilon) + { + // Regular case + //----------------- + if(d * d <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + // If the curvature doesn't exceed the distance_tolerance value + // we tend to finish subdivisions. + //---------------------- + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x123, y123)); + return; + } + // Angle & Cusp Condition + //---------------------- + da = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1)); + if(da >= pi) da = 2*pi - da; + if(da < m_angle_tolerance) + { + // Finally we can stop the recursion + //---------------------- + m_points.add(point_d(x123, y123)); + return; + } + } + } + else + { + // Collinear case + //------------------ + da = dx*dx + dy*dy; + if(da == 0) + { + d = calc_sq_distance(x1, y1, x2, y2); + } + else + { + d = ((x2 - x1)*dx + (y2 - y1)*dy) / da; + if(d > 0 && d < 1) + { + // Simple collinear case, 1---2---3 + // We can leave just two endpoints + return; + } + if(d <= 0) d = calc_sq_distance(x2, y2, x1, y1); + else if(d >= 1) d = calc_sq_distance(x2, y2, x3, y3); + else d = calc_sq_distance(x2, y2, x1 + d*dx, y1 + d*dy); + } + if(d < m_distance_tolerance_square) + { + m_points.add(point_d(x2, y2)); + return; + } + } + // Continue subdivision + //---------------------- + recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1); + recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1); + } + + //------------------------------------------------------------------------ + void curve3_div::bezier(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_points.add(point_d(x1, y1)); + recursive_bezier(x1, y1, x2, y2, x3, y3, 0); + m_points.add(point_d(x3, y3)); + } //------------------------------------------------------------------------ - void curve4::init(double x1, double y1, - double x2, double y2, - double x3, double y3, - double x4, double y4) + void curve4_inc::approximation_scale(double s) + { + m_scale = s; + } + + //------------------------------------------------------------------------ + double curve4_inc::approximation_scale() const + { + return m_scale; + } + + //------------------------------------------------------------------------ + static double MSC60_fix_ICE(double v) { return v; } + + //------------------------------------------------------------------------ + void curve4_inc::init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) { m_start_x = x1; m_start_y = y1; @@ -144,25 +273,29 @@ namespace agg double dx3 = x4 - x3; double dy3 = y4 - y3; - double len = sqrt(dx1 * dx1 + dy1 * dy1) + - sqrt(dx2 * dx2 + dy2 * dy2) + - sqrt(dx3 * dx3 + dy3 * dy3); + double len = (sqrt(dx1 * dx1 + dy1 * dy1) + + sqrt(dx2 * dx2 + dy2 * dy2) + + sqrt(dx3 * dx3 + dy3 * dy3)) * 0.25 * m_scale; - m_num_steps = int(len * 0.25 * m_scale); +#if defined(_MSC_VER) && _MSC_VER <= 1200 + m_num_steps = uround(MSC60_fix_ICE(len)); +#else + m_num_steps = uround(len); +#endif - if(m_num_steps < 2) + if(m_num_steps < 4) { - m_num_steps = 2; + m_num_steps = 4; } double subdivide_step = 1.0 / m_num_steps; double subdivide_step2 = subdivide_step * subdivide_step; double subdivide_step3 = subdivide_step * subdivide_step * subdivide_step; - double pre1 = 3.0 * subdivide_step; - double pre2 = 3.0 * subdivide_step2; - double pre4 = 6.0 * subdivide_step2; - double pre5 = 6.0 * subdivide_step3; + double pre1 = 3.0 * subdivide_step; + double pre2 = 3.0 * subdivide_step2; + double pre4 = 6.0 * subdivide_step2; + double pre5 = 6.0 * subdivide_step3; double tmp1x = x1 - x2 * 2.0 + x3; double tmp1y = y1 - y2 * 2.0 + y3; @@ -185,11 +318,8 @@ namespace agg m_step = m_num_steps; } - - - //------------------------------------------------------------------------ - void curve4::rewind(unsigned) + void curve4_inc::rewind(unsigned) { if(m_num_steps == 0) { @@ -205,12 +335,8 @@ namespace agg m_ddfy = m_saved_ddfy; } - - - - //------------------------------------------------------------------------ - unsigned curve4::vertex(double* x, double* y) + unsigned curve4_inc::vertex(double* x, double* y) { if(m_step < 0) return path_cmd_stop; if(m_step == m_num_steps) @@ -220,6 +346,7 @@ namespace agg --m_step; return path_cmd_move_to; } + if(m_step == 0) { *x = m_end_x; @@ -227,12 +354,14 @@ namespace agg --m_step; return path_cmd_line_to; } - m_fx += m_dfx; + + m_fx += m_dfx; m_fy += m_dfy; m_dfx += m_ddfx; m_dfy += m_ddfy; m_ddfx += m_dddfx; m_ddfy += m_dddfy; + *x = m_fx; *y = m_fy; --m_step; @@ -242,5 +371,241 @@ namespace agg + //------------------------------------------------------------------------ + void curve4_div::init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_points.remove_all(); + m_distance_tolerance_square = 0.5 / m_approximation_scale; + m_distance_tolerance_square *= m_distance_tolerance_square; + bezier(x1, y1, x2, y2, x3, y3, x4, y4); + m_count = 0; + } + + //------------------------------------------------------------------------ + void curve4_div::recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4, + unsigned level) + { + if(level > curve_recursion_limit) + { + return; + } + + // Calculate all the mid-points of the line segments + //---------------------- + double x12 = (x1 + x2) / 2; + double y12 = (y1 + y2) / 2; + double x23 = (x2 + x3) / 2; + double y23 = (y2 + y3) / 2; + double x34 = (x3 + x4) / 2; + double y34 = (y3 + y4) / 2; + double x123 = (x12 + x23) / 2; + double y123 = (y12 + y23) / 2; + double x234 = (x23 + x34) / 2; + double y234 = (y23 + y34) / 2; + double x1234 = (x123 + x234) / 2; + double y1234 = (y123 + y234) / 2; + + + // Try to approximate the full cubic curve by a single straight line + //------------------ + double dx = x4-x1; + double dy = y4-y1; + + double d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx)); + double d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx)); + double da1, da2, k; + + switch((int(d2 > curve_collinearity_epsilon) << 1) + + int(d3 > curve_collinearity_epsilon)) + { + case 0: + // All collinear OR p1==p4 + //---------------------- + k = dx*dx + dy*dy; + if(k == 0) + { + d2 = calc_sq_distance(x1, y1, x2, y2); + d3 = calc_sq_distance(x4, y4, x3, y3); + } + else + { + k = 1 / k; + da1 = x2 - x1; + da2 = y2 - y1; + d2 = k * (da1*dx + da2*dy); + da1 = x3 - x1; + da2 = y3 - y1; + d3 = k * (da1*dx + da2*dy); + if(d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1) + { + // Simple collinear case, 1---2---3---4 + // We can leave just two endpoints + return; + } + if(d2 <= 0) d2 = calc_sq_distance(x2, y2, x1, y1); + else if(d2 >= 1) d2 = calc_sq_distance(x2, y2, x4, y4); + else d2 = calc_sq_distance(x2, y2, x1 + d2*dx, y1 + d2*dy); + + if(d3 <= 0) d3 = calc_sq_distance(x3, y3, x1, y1); + else if(d3 >= 1) d3 = calc_sq_distance(x3, y3, x4, y4); + else d3 = calc_sq_distance(x3, y3, x1 + d3*dx, y1 + d3*dy); + } + if(d2 > d3) + { + if(d2 < m_distance_tolerance_square) + { + m_points.add(point_d(x2, y2)); + return; + } + } + else + { + if(d3 < m_distance_tolerance_square) + { + m_points.add(point_d(x3, y3)); + return; + } + } + break; + + case 1: + // p1,p2,p4 are collinear, p3 is significant + //---------------------- + if(d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x23, y23)); + return; + } + + // Angle Condition + //---------------------- + da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2)); + if(da1 >= pi) da1 = 2*pi - da1; + + if(da1 < m_angle_tolerance) + { + m_points.add(point_d(x2, y2)); + m_points.add(point_d(x3, y3)); + return; + } + + if(m_cusp_limit != 0.0) + { + if(da1 > m_cusp_limit) + { + m_points.add(point_d(x3, y3)); + return; + } + } + } + break; + + case 2: + // p1,p3,p4 are collinear, p2 is significant + //---------------------- + if(d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x23, y23)); + return; + } + + // Angle Condition + //---------------------- + da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1)); + if(da1 >= pi) da1 = 2*pi - da1; + + if(da1 < m_angle_tolerance) + { + m_points.add(point_d(x2, y2)); + m_points.add(point_d(x3, y3)); + return; + } + + if(m_cusp_limit != 0.0) + { + if(da1 > m_cusp_limit) + { + m_points.add(point_d(x2, y2)); + return; + } + } + } + break; + + case 3: + // Regular case + //----------------- + if((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + // If the curvature doesn't exceed the distance_tolerance value + // we tend to finish subdivisions. + //---------------------- + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x23, y23)); + return; + } + + // Angle & Cusp Condition + //---------------------- + k = atan2(y3 - y2, x3 - x2); + da1 = fabs(k - atan2(y2 - y1, x2 - x1)); + da2 = fabs(atan2(y4 - y3, x4 - x3) - k); + if(da1 >= pi) da1 = 2*pi - da1; + if(da2 >= pi) da2 = 2*pi - da2; + + if(da1 + da2 < m_angle_tolerance) + { + // Finally we can stop the recursion + //---------------------- + m_points.add(point_d(x23, y23)); + return; + } + + if(m_cusp_limit != 0.0) + { + if(da1 > m_cusp_limit) + { + m_points.add(point_d(x2, y2)); + return; + } + + if(da2 > m_cusp_limit) + { + m_points.add(point_d(x3, y3)); + return; + } + } + } + break; + } + + // Continue subdivision + //---------------------- + recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); + recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); + } + + //------------------------------------------------------------------------ + void curve4_div::bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_points.add(point_d(x1, y1)); + recursive_bezier(x1, y1, x2, y2, x3, y3, x4, y4, 0); + m_points.add(point_d(x4, y4)); + } + } diff --git a/src/libs/agg/src/agg_embedded_raster_fonts.cpp b/src/libs/agg/src/agg_embedded_raster_fonts.cpp index f8148fb6fd..ee4dc65ee4 100644 --- a/src/libs/agg/src/agg_embedded_raster_fonts.cpp +++ b/src/libs/agg/src/agg_embedded_raster_fonts.cpp @@ -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. diff --git a/src/libs/agg/src/agg_gsv_text.cpp b/src/libs/agg/src/agg_gsv_text.cpp index 59d62403a4..901e2c532d 100644 --- a/src/libs/agg/src/agg_gsv_text.cpp +++ b/src/libs/agg/src/agg_gsv_text.cpp @@ -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. @@ -480,16 +480,6 @@ namespace agg 0xf6,0xfa,0x04,0x06,0x08,0xfa }; - - - //------------------------------------------------------------------------- - gsv_text::~gsv_text() - { - if(m_loaded_font) delete [] m_loaded_font; - if(m_text_buf) delete [] m_text_buf; - } - - //------------------------------------------------------------------------- gsv_text::gsv_text() : m_x(0.0), @@ -500,11 +490,10 @@ namespace agg m_space(0.0), m_line_space(0.0), m_text(m_chr), - m_text_buf(0), - m_buf_size(0), + m_text_buf(), m_cur_chr(m_chr), m_font(gsv_default_font), - m_loaded_font(0), + m_loaded_font(), m_status(initial), m_big_endian(false), m_flip(false) @@ -521,7 +510,7 @@ namespace agg void gsv_text::font(const void* font) { m_font = font; - if(m_font == 0) m_font = m_loaded_font; + if(m_font == 0) m_font = &m_loaded_font[0]; } //------------------------------------------------------------------------- @@ -555,9 +544,7 @@ namespace agg //------------------------------------------------------------------------- void gsv_text::load_font(const char* file) { - if(m_loaded_font) delete [] m_loaded_font; - m_loaded_font = 0; - + m_loaded_font.resize(0); FILE* fd = fopen(file, "rb"); if(fd) { @@ -568,9 +555,9 @@ namespace agg fseek(fd, 0l, SEEK_SET); if(len > 0) { - m_loaded_font = new char [len]; - fread(m_loaded_font, 1, len, fd); - m_font = m_loaded_font; + m_loaded_font.resize(len); + fread(&m_loaded_font[0], 1, len, fd); + m_font = &m_loaded_font[0]; } fclose(fd); } @@ -587,13 +574,12 @@ namespace agg return; } unsigned new_size = strlen(text) + 1; - if(new_size > m_buf_size) + if(new_size > m_text_buf.size()) { - if(m_text_buf) delete [] m_text_buf; - m_text_buf = new char [m_buf_size = new_size]; + m_text_buf.resize(new_size); } - memcpy(m_text_buf, text, new_size); - m_text = m_text_buf; + memcpy(&m_text_buf[0], text, new_size); + m_text = &m_text_buf[0]; } diff --git a/src/libs/agg/src/agg_image_filters.cpp b/src/libs/agg/src/agg_image_filters.cpp index ceb5024a8e..549d9adbf5 100644 --- a/src/libs/agg/src/agg_image_filters.cpp +++ b/src/libs/agg/src/agg_image_filters.cpp @@ -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. @@ -13,7 +13,7 @@ // http://www.antigrain.com //---------------------------------------------------------------------------- // -// Filtering class image_filter_base implemantation +// Filtering class image_filter_lut implemantation // //---------------------------------------------------------------------------- @@ -23,38 +23,20 @@ namespace agg { - //-------------------------------------------------------------------- - image_filter_base::~image_filter_base() + void image_filter_lut::realloc_lut(double radius) { - delete [] m_weight_array_int; - delete [] m_weight_array_dbl; + m_radius = radius; + m_diameter = uceil(radius) * 2; + m_start = -int(m_diameter / 2 - 1); + unsigned size = m_diameter << image_subpixel_shift; + if(size > m_weight_array.size()) + { + m_weight_array.resize(size); + } } - //-------------------------------------------------------------------- - image_filter_base::image_filter_base(unsigned dimension) : - m_dimension(dimension), - m_start(-int(dimension / 2 - 1)), - m_weight_array_dbl(new double [dimension << image_subpixel_shift]), - m_weight_array_int(new int [dimension << image_subpixel_shift]) - { - } - - - //-------------------------------------------------------------------- - void image_filter_base::weight(unsigned idx, double val) - { - m_weight_array_dbl[idx] = val; - m_weight_array_int[idx] = int(val * image_filter_size); - } - - //-------------------------------------------------------------------- - double image_filter_base::calc_x(unsigned idx) const - { - return double(idx) / double(image_subpixel_size) - - double(m_dimension / 2); - } //-------------------------------------------------------------------- // This function normalizes integer values and corrects the rounding @@ -63,41 +45,59 @@ namespace agg // of 1.0 which means that any sum of pixel weights must be equal to 1.0. // So, the filter function must produce a graph of the proper shape. //-------------------------------------------------------------------- - void image_filter_base::normalize() + void image_filter_lut::normalize() { unsigned i; int flip = 1; - for(i = 0; i < image_subpixel_size; i++) + for(i = 0; i < image_subpixel_scale; i++) { for(;;) { int sum = 0; unsigned j; - for(j = 0; j < m_dimension; j++) + for(j = 0; j < m_diameter; j++) { - sum += m_weight_array_int[j * image_subpixel_size + i]; + sum += m_weight_array[j * image_subpixel_scale + i]; } - sum -= image_filter_size; - if(sum == 0) break; + if(sum == image_filter_scale) break; + double k = double(image_filter_scale) / double(sum); + sum = 0; + for(j = 0; j < m_diameter; j++) + { + sum += m_weight_array[j * image_subpixel_scale + i] = + iround(m_weight_array[j * image_subpixel_scale + i] * k); + } + + sum -= image_filter_scale; int inc = (sum > 0) ? -1 : 1; - for(j = 0; j < m_dimension && sum; j++) + for(j = 0; j < m_diameter && sum; j++) { flip ^= 1; - unsigned idx = flip ? m_dimension/2 + j/2 : m_dimension/2 - j/2; - int v = m_weight_array_int[idx * image_subpixel_size + i]; - if(v < image_filter_size) + unsigned idx = flip ? m_diameter/2 + j/2 : m_diameter/2 - j/2; + int v = m_weight_array[idx * image_subpixel_scale + i]; + if(v < image_filter_scale) { - m_weight_array_int[idx * image_subpixel_size + i] += inc; + m_weight_array[idx * image_subpixel_scale + i] += inc; sum += inc; } } } } + + unsigned pivot = m_diameter << (image_subpixel_shift - 1); + + for(i = 0; i < pivot; i++) + { + m_weight_array[pivot + i] = m_weight_array[pivot - i]; + } + unsigned end = (diameter() << image_subpixel_shift) - 1; + m_weight_array[0] = m_weight_array[end]; } + } diff --git a/src/libs/agg/src/agg_line_aa_basics.cpp b/src/libs/agg/src/agg_line_aa_basics.cpp index 568c62db7e..018d65366f 100644 --- a/src/libs/agg/src/agg_line_aa_basics.cpp +++ b/src/libs/agg/src/agg_line_aa_basics.cpp @@ -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,9 +41,9 @@ namespace agg // (7)111 | 101(5) // [2] | [3] // <3> - // 0,1,2,3,4,5,6,7 - int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 }; - int8u line_parameters::s_diagonal_quadrant[8] = { 0,1,2,1,0,3,2,3 }; + // 0,1,2,3,4,5,6,7 + const int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 }; + const int8u line_parameters::s_diagonal_quadrant[8] = { 0,1,2,1,0,3,2,3 }; @@ -69,13 +69,14 @@ namespace agg // Check if the bisectrix is too short double dx = tx - l2.x1; double dy = ty - l2.y1; - if((int)sqrt(dx * dx + dy * dy) < line_subpixel_size) + if((int)sqrt(dx * dx + dy * dy) < line_subpixel_scale) { - tx = (l2.x1 + l2.x1 + (l2.y1 - l1.y1) + (l2.y2 - l2.y1)) / 2; - ty = (l2.y1 + l2.y1 - (l2.x1 - l1.x1) - (l2.x2 - l2.x1)) / 2; + *x = (l2.x1 + l2.x1 + (l2.y1 - l1.y1) + (l2.y2 - l2.y1)) >> 1; + *y = (l2.y1 + l2.y1 - (l2.x1 - l1.x1) - (l2.x2 - l2.x1)) >> 1; + return; } - *x = int(tx); - *y = int(ty); + *x = iround(tx); + *y = iround(ty); } } diff --git a/src/libs/agg/src/agg_line_profile_aa.cpp b/src/libs/agg/src/agg_line_profile_aa.cpp index ba12394b89..6066662cb9 100644 --- a/src/libs/agg/src/agg_line_profile_aa.cpp +++ b/src/libs/agg/src/agg_line_profile_aa.cpp @@ -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. @@ -42,14 +42,13 @@ namespace agg //--------------------------------------------------------------------- line_profile_aa::value_type* line_profile_aa::profile(double w) { - m_subpixel_width = int(w * subpixel_size); - unsigned size = m_subpixel_width + subpixel_size * 6; - if(size > m_size) + m_subpixel_width = uround(w * subpixel_scale); + unsigned size = m_subpixel_width + subpixel_scale * 6; + if(size > m_profile.size()) { - delete [] m_profile; - m_profile = new value_type[m_size = size]; + m_profile.resize(size); } - return m_profile; + return &m_profile[0]; } @@ -57,8 +56,8 @@ namespace agg void line_profile_aa::set(double center_width, double smoother_width) { double base_val = 1.0; - if(center_width == 0.0) center_width = 1.0 / subpixel_size; - if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_size; + if(center_width == 0.0) center_width = 1.0 / subpixel_scale; + if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_scale; double width = center_width + smoother_width; if(width < m_min_width) @@ -71,10 +70,10 @@ namespace agg value_type* ch = profile(center_width + smoother_width); - unsigned subpixel_center_width = unsigned(center_width * subpixel_size); - unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_size); + unsigned subpixel_center_width = unsigned(center_width * subpixel_scale); + unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_scale); - value_type* ch_center = ch + subpixel_size*2; + value_type* ch_center = ch + subpixel_scale*2; value_type* ch_smoother = ch_center + subpixel_center_width; unsigned i; @@ -97,7 +96,7 @@ namespace agg unsigned n_smoother = profile_size() - subpixel_smoother_width - subpixel_center_width - - subpixel_size*2; + subpixel_scale*2; val = m_gamma[0]; for(i = 0; i < n_smoother; i++) @@ -106,7 +105,7 @@ namespace agg } ch = ch_center; - for(i = 0; i < subpixel_size*2; i++) + for(i = 0; i < subpixel_scale*2; i++) { *--ch = *ch_center++; } diff --git a/src/libs/agg/src/agg_path_storage.cpp b/src/libs/agg/src/agg_path_storage.cpp deleted file mode 100644 index ab94cb63db..0000000000 --- a/src/libs/agg/src/agg_path_storage.cpp +++ /dev/null @@ -1,525 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Class path_storage -// -//---------------------------------------------------------------------------- -#include -#include -#include "agg_path_storage.h" -#include "agg_math.h" -#include "agg_bezier_arc.h" - - -namespace agg -{ - - //------------------------------------------------------------------------ - path_storage::~path_storage() - { - if(m_total_blocks) - { - double** coord_blk = m_coord_blocks + m_total_blocks - 1; - while(m_total_blocks--) - { - delete [] *coord_blk; - --coord_blk; - } - delete [] m_coord_blocks; - } - } - - - //------------------------------------------------------------------------ - path_storage::path_storage() : - m_total_vertices(0), - m_total_blocks(0), - m_max_blocks(0), - m_coord_blocks(0), - m_cmd_blocks(0), - m_iterator(0) - { - } - - - //------------------------------------------------------------------------ - path_storage::path_storage(const path_storage& ps) : - m_total_vertices(0), - m_total_blocks(0), - m_max_blocks(0), - m_coord_blocks(0), - m_cmd_blocks(0), - m_iterator(0) - { - copy_from(ps); - } - - - //------------------------------------------------------------------------ - void path_storage::remove_all() - { - m_total_vertices = 0; - m_iterator = 0; - } - - - //------------------------------------------------------------------------ - void path_storage::copy_from(const path_storage& ps) - { - remove_all(); - unsigned i; - for(i = 0; i < ps.total_vertices(); i++) - { - double x, y; - unsigned cmd = ps.vertex(i, &x, &y); - add_vertex(x, y, cmd); - } - } - - - //------------------------------------------------------------------------ - void path_storage::allocate_block(unsigned nb) - { - if(nb >= m_max_blocks) - { - double** new_coords = - new double* [(m_max_blocks + block_pool) * 2]; - - unsigned char** new_cmds = - (unsigned char**)(new_coords + m_max_blocks + block_pool); - - if(m_coord_blocks) - { - memcpy(new_coords, - m_coord_blocks, - m_max_blocks * sizeof(double*)); - - memcpy(new_cmds, - m_cmd_blocks, - m_max_blocks * sizeof(unsigned char*)); - - delete [] m_coord_blocks; - } - m_coord_blocks = new_coords; - m_cmd_blocks = new_cmds; - m_max_blocks += block_pool; - } - m_coord_blocks[nb] = - new double [block_size * 2 + - block_size / - (sizeof(double) / sizeof(unsigned char))]; - - m_cmd_blocks[nb] = - (unsigned char*)(m_coord_blocks[nb] + block_size * 2); - - m_total_blocks++; - } - - - //------------------------------------------------------------------------ - void path_storage::rewind(unsigned path_id) - { - m_iterator = path_id; - } - - - - //------------------------------------------------------------------------ - void path_storage::arc_to(double rx, double ry, - double angle, - bool large_arc_flag, - bool sweep_flag, - double x, double y) - { - if(m_total_vertices && is_vertex(command(m_total_vertices - 1))) - { - const double epsilon = 1e-30; - double x0 = 0.0; - double y0 = 0.0; - last_vertex(&x0, &y0); - - rx = fabs(rx); - ry = fabs(ry); - - // Ensure radii are valid - //------------------------- - if(rx < epsilon || ry < epsilon) - { - line_to(x, y); - return; - } - - if(calc_distance(x0, y0, x, y) < epsilon) - { - // If the endpoints (x, y) and (x0, y0) are identical, then this - // is equivalent to omitting the elliptical arc segment entirely. - return; - } - bezier_arc_svg a(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x, y); - if(a.radii_ok()) - { - add_path(a, 0, true); - } - else - { - line_to(x, y); - } - } - else - { - move_to(x, y); - } - } - - - //------------------------------------------------------------------------ - void path_storage::arc_rel(double rx, double ry, - double angle, - bool large_arc_flag, - bool sweep_flag, - double dx, double dy) - { - rel_to_abs(&dx, &dy); - arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy); - } - - - //------------------------------------------------------------------------ - void path_storage::curve3(double x_ctrl, double y_ctrl, - double x_to, double y_to) - { - add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); - add_vertex(x_to, y_to, path_cmd_curve3); - } - - //------------------------------------------------------------------------ - void path_storage::curve3_rel(double dx_ctrl, double dy_ctrl, - double dx_to, double dy_to) - { - rel_to_abs(&dx_ctrl, &dy_ctrl); - rel_to_abs(&dx_to, &dy_to); - add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3); - add_vertex(dx_to, dy_to, path_cmd_curve3); - } - - //------------------------------------------------------------------------ - void path_storage::curve3(double x_to, double y_to) - { - double x0; - double y0; - if(is_vertex(last_vertex(&x0, &y0))) - { - double x_ctrl; - double y_ctrl; - unsigned cmd = prev_vertex(&x_ctrl, &y_ctrl); - if(is_curve(cmd)) - { - x_ctrl = x0 + x0 - x_ctrl; - y_ctrl = y0 + y0 - y_ctrl; - } - else - { - x_ctrl = x0; - y_ctrl = y0; - } - curve3(x_ctrl, y_ctrl, x_to, y_to); - } - } - - - //------------------------------------------------------------------------ - void path_storage::curve3_rel(double dx_to, double dy_to) - { - rel_to_abs(&dx_to, &dy_to); - curve3(dx_to, dy_to); - } - - - //------------------------------------------------------------------------ - void path_storage::curve4(double x_ctrl1, double y_ctrl1, - double x_ctrl2, double y_ctrl2, - double x_to, double y_to) - { - add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); - add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4); - add_vertex(x_to, y_to, path_cmd_curve4); - } - - //------------------------------------------------------------------------ - void path_storage::curve4_rel(double dx_ctrl1, double dy_ctrl1, - double dx_ctrl2, double dy_ctrl2, - double dx_to, double dy_to) - { - rel_to_abs(&dx_ctrl1, &dy_ctrl1); - rel_to_abs(&dx_ctrl2, &dy_ctrl2); - rel_to_abs(&dx_to, &dy_to); - add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4); - add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4); - add_vertex(dx_to, dy_to, path_cmd_curve4); - } - - - //------------------------------------------------------------------------ - void path_storage::curve4(double x_ctrl2, double y_ctrl2, - double x_to, double y_to) - { - double x0; - double y0; - if(is_vertex(last_vertex(&x0, &y0))) - { - double x_ctrl1; - double y_ctrl1; - unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1); - if(is_curve(cmd)) - { - x_ctrl1 = x0 + x0 - x_ctrl1; - y_ctrl1 = y0 + y0 - y_ctrl1; - } - else - { - x_ctrl1 = x0; - y_ctrl1 = y0; - } - curve4(x_ctrl1, y_ctrl1, x_ctrl2, y_ctrl2, x_to, y_to); - } - } - - - //------------------------------------------------------------------------ - void path_storage::curve4_rel(double dx_ctrl2, double dy_ctrl2, - double dx_to, double dy_to) - { - rel_to_abs(&dx_ctrl2, &dy_ctrl2); - rel_to_abs(&dx_to, &dy_to); - curve4(dx_ctrl2, dy_ctrl2, dx_to, dy_to); - } - - - //------------------------------------------------------------------------ - void path_storage::end_poly(unsigned flags) - { - if(m_total_vertices) - { - if(is_vertex(command(m_total_vertices - 1))) - { - add_vertex(0.0, 0.0, path_cmd_end_poly | flags); - } - } - } - - - //------------------------------------------------------------------------ - unsigned path_storage::start_new_path() - { - if(m_total_vertices) - { - if(!is_stop(command(m_total_vertices - 1))) - { - add_vertex(0.0, 0.0, path_cmd_stop); - } - } - return m_total_vertices; - } - - - //------------------------------------------------------------------------ - void path_storage::add_poly(const double* vertices, unsigned num, - bool solid_path, unsigned end_flags) - { - if(num) - { - if(!solid_path) - { - move_to(vertices[0], vertices[1]); - vertices += 2; - --num; - } - while(num--) - { - line_to(vertices[0], vertices[1]); - vertices += 2; - } - if(end_flags) end_poly(end_flags); - } - } - - - //------------------------------------------------------------------------ - unsigned path_storage::perceive_polygon_orientation(unsigned idx, - double xs, double ys, - unsigned* orientation) - { - unsigned i; - double sum = 0.0; - double x, y, xn, yn; - - x = xs; - y = ys; - for(i = idx; i < m_total_vertices; ++i) - { - if(is_next_poly(vertex(i, &xn, &yn))) break; - sum += x * yn - y * xn; - x = xn; - y = yn; - } - if(i > idx) sum += x * ys - y * xs; - *orientation = path_flags_none; - if(sum != 0.0) - { - *orientation = (sum < 0.0) ? path_flags_cw : path_flags_ccw; - } - return i; - } - - - //------------------------------------------------------------------------ - void path_storage::reverse_polygon(unsigned start, unsigned end) - { - unsigned i; - unsigned tmp_cmd = command(start); - - // Shift all commands to one position - for(i = start; i < end; i++) - { - modify_command(i, command(i + 1)); - } - - // Assign starting command to the ending command - modify_command(end, tmp_cmd); - - // Reverse the polygon - while(end > start) - { - unsigned start_nb = start >> block_shift; - unsigned end_nb = end >> block_shift; - double* start_ptr = m_coord_blocks[start_nb] + ((start & block_mask) << 1); - double* end_ptr = m_coord_blocks[end_nb] + ((end & block_mask) << 1); - double tmp_xy; - - tmp_xy = *start_ptr; - *start_ptr++ = *end_ptr; - *end_ptr++ = tmp_xy; - - tmp_xy = *start_ptr; - *start_ptr = *end_ptr; - *end_ptr = tmp_xy; - - tmp_cmd = m_cmd_blocks[start_nb][start & block_mask]; - m_cmd_blocks[start_nb][start & block_mask] = m_cmd_blocks[end_nb][end & block_mask]; - m_cmd_blocks[end_nb][end & block_mask] = (unsigned char)tmp_cmd; - - ++start; - --end; - } - } - - - //------------------------------------------------------------------------ - unsigned path_storage::arrange_orientations(unsigned path_id, - path_flags_e new_orientation) - { - unsigned end = m_total_vertices; - if(m_total_vertices && new_orientation != path_flags_none) - { - unsigned start = path_id; - - double xs, ys; - unsigned cmd = vertex(start, &xs, &ys); - unsigned inc = 0; - for(;;) - { - unsigned orientation; - end = perceive_polygon_orientation(start + 1, xs, ys, - &orientation); - if(end > start + 2 && - orientation && - orientation != unsigned(new_orientation)) - { - reverse_polygon(start + inc, end - 1); - } - if(end >= m_total_vertices) break; - cmd = command(end); - if(is_stop(cmd)) - { - ++end; - break; - } - if(is_end_poly(cmd)) - { - inc = 1; - modify_command(end, set_orientation(cmd, new_orientation)); - } - else - { - cmd = vertex(++end, &xs, &ys); - inc = 0; - } - start = end; - } - } - return end; - } - - - - //------------------------------------------------------------------------ - void path_storage::arrange_orientations_all_paths(path_flags_e new_orientation) - { - if(new_orientation != path_flags_none) - { - unsigned start = 0; - while(start < m_total_vertices) - { - start = arrange_orientations(start, new_orientation); - } - } - } - - - - //------------------------------------------------------------------------ - void path_storage::flip_x(double x1, double x2) - { - unsigned i; - double x, y; - for(i = 0; i < m_total_vertices; i++) - { - unsigned cmd = vertex(i, &x, &y); - if(is_vertex(cmd)) - { - modify_vertex(i, x2 - x + x1, y); - } - } - } - - - //------------------------------------------------------------------------ - void path_storage::flip_y(double y1, double y2) - { - unsigned i; - double x, y; - for(i = 0; i < m_total_vertices; i++) - { - unsigned cmd = vertex(i, &x, &y); - if(is_vertex(cmd)) - { - modify_vertex(i, x, y2 - y + y1); - } - } - } - - -} - diff --git a/src/libs/agg/src/agg_rasterizer_scanline_aa.cpp b/src/libs/agg/src/agg_rasterizer_scanline_aa.cpp deleted file mode 100644 index 9d3c0e31a5..0000000000 --- a/src/libs/agg/src/agg_rasterizer_scanline_aa.cpp +++ /dev/null @@ -1,621 +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. -// -// 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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Class outline_aa - implementation. -// -// Initially the rendering algorithm was designed by David Turner and the -// other authors of the FreeType library - see the above notice. I nearly -// created a similar renderer, but still I was far from David's work. -// I completely redesigned the original code and adapted it for Anti-Grain -// ideas. Two functions - render_line and render_hline are the core of -// the algorithm - they calculate the exact coverage of each pixel cell -// of the polygon. I left these functions almost as is, because there's -// no way to improve the perfection - hats off to David and his group! -// -// All other code is very different from the original. -// -//---------------------------------------------------------------------------- - -#include -#include "agg_rasterizer_scanline_aa.h" - - -namespace agg -{ - - //------------------------------------------------------------------------ - inline void cell_aa::set_cover(int c, int a) - { - cover = c; - area = a; - } - - //------------------------------------------------------------------------ - inline void cell_aa::add_cover(int c, int a) - { - cover += c; - area += a; - } - - //------------------------------------------------------------------------ - inline void cell_aa::set_coord(int cx, int cy) - { - x = int16(cx); - y = int16(cy); - packed_coord = (cy << 16) + cx; - } - - //------------------------------------------------------------------------ - inline void cell_aa::set(int cx, int cy, int c, int a) - { - x = int16(cx); - y = int16(cy); - packed_coord = (cy << 16) + cx; - cover = c; - area = a; - } - - //------------------------------------------------------------------------ - outline_aa::~outline_aa() - { - delete [] m_sorted_cells; - if(m_num_blocks) - { - cell_aa** ptr = m_cells + m_num_blocks - 1; - while(m_num_blocks--) - { - delete [] *ptr; - ptr--; - } - delete [] m_cells; - } - } - - - //------------------------------------------------------------------------ - outline_aa::outline_aa() : - m_num_blocks(0), - m_max_blocks(0), - m_cur_block(0), - m_num_cells(0), - m_cells(0), - m_cur_cell_ptr(0), - m_sorted_cells(0), - m_sorted_size(0), - m_cur_x(0), - m_cur_y(0), - m_min_x(0x7FFFFFFF), - m_min_y(0x7FFFFFFF), - m_max_x(-0x7FFFFFFF), - m_max_y(-0x7FFFFFFF), - m_sorted(false) - { - m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0); - } - - - //------------------------------------------------------------------------ - void outline_aa::reset() - { - m_num_cells = 0; - m_cur_block = 0; - m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0); - m_sorted = false; - m_min_x = 0x7FFFFFFF; - m_min_y = 0x7FFFFFFF; - m_max_x = -0x7FFFFFFF; - m_max_y = -0x7FFFFFFF; - } - - - - //------------------------------------------------------------------------ - void outline_aa::allocate_block() - { - if(m_cur_block >= m_num_blocks) - { - if(m_num_blocks >= m_max_blocks) - { - cell_aa** new_cells = new cell_aa* [m_max_blocks + cell_block_pool]; - if(m_cells) - { - memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_aa*)); - delete [] m_cells; - } - m_cells = new_cells; - m_max_blocks += cell_block_pool; - } - m_cells[m_num_blocks++] = new cell_aa [unsigned(cell_block_size)]; - } - m_cur_cell_ptr = m_cells[m_cur_block++]; - } - - - //------------------------------------------------------------------------ - inline void outline_aa::add_cur_cell() - { - if(m_cur_cell.area | m_cur_cell.cover) - { - if((m_num_cells & cell_block_mask) == 0) - { - if(m_num_blocks >= cell_block_limit) return; - allocate_block(); - } - *m_cur_cell_ptr++ = m_cur_cell; - ++m_num_cells; - if(m_cur_cell.x < m_min_x) m_min_x = m_cur_cell.x; - if(m_cur_cell.x > m_max_x) m_max_x = m_cur_cell.x; - } - } - - - - //------------------------------------------------------------------------ - inline void outline_aa::set_cur_cell(int x, int y) - { - if(m_cur_cell.packed_coord != (y << 16) + x) - { - add_cur_cell(); - m_cur_cell.set(x, y, 0, 0); - } - } - - - - //------------------------------------------------------------------------ - inline void outline_aa::render_hline(int ey, int x1, int y1, int x2, int y2) - { - int ex1 = x1 >> poly_base_shift; - int ex2 = x2 >> poly_base_shift; - int fx1 = x1 & poly_base_mask; - int fx2 = x2 & poly_base_mask; - - int delta, p, first, dx; - int incr, lift, mod, rem; - - //trivial case. Happens often - if(y1 == y2) - { - set_cur_cell(ex2, ey); - return; - } - - //everything is located in a single cell. That is easy! - if(ex1 == ex2) - { - delta = y2 - y1; - m_cur_cell.add_cover(delta, (fx1 + fx2) * delta); - return; - } - - //ok, we'll have to render a run of adjacent cells on the same - //hline... - p = (poly_base_size - fx1) * (y2 - y1); - first = poly_base_size; - 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_cur_cell.add_cover(delta, (fx1 + first) * delta); - - ex1 += incr; - set_cur_cell(ex1, ey); - y1 += delta; - - if(ex1 != ex2) - { - p = poly_base_size * (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_cur_cell.add_cover(delta, (poly_base_size) * delta); - y1 += delta; - ex1 += incr; - set_cur_cell(ex1, ey); - } - } - delta = y2 - y1; - m_cur_cell.add_cover(delta, (fx2 + poly_base_size - first) * delta); - } - - - - - - - //------------------------------------------------------------------------ - void outline_aa::render_line(int x1, int y1, int x2, int y2) - { - int ey1 = y1 >> poly_base_shift; - int ey2 = y2 >> poly_base_shift; - int fy1 = y1 & poly_base_mask; - int fy2 = y2 & poly_base_mask; - - int dx, dy, x_from, x_to; - int p, rem, mod, lift, delta, first, incr; - - dx = x2 - x1; - dy = y2 - y1; - - //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_base_shift; - int two_fx = (x1 - (ex << poly_base_shift)) << 1; - int area; - - first = poly_base_size; - if(dy < 0) - { - first = 0; - incr = -1; - } - - x_from = x1; - - //render_hline(ey1, x_from, fy1, x_from, first); - delta = first - fy1; - m_cur_cell.add_cover(delta, two_fx * delta); - - ey1 += incr; - set_cur_cell(ex, ey1); - - delta = first + first - poly_base_size; - area = two_fx * delta; - while(ey1 != ey2) - { - //render_hline(ey1, x_from, poly_base_size - first, x_from, first); - m_cur_cell.set_cover(delta, area); - ey1 += incr; - set_cur_cell(ex, ey1); - } - //render_hline(ey1, x_from, poly_base_size - first, x_from, fy2); - delta = fy2 - poly_base_size + first; - m_cur_cell.add_cover(delta, two_fx * delta); - return; - } - - //ok, we have to render several hlines - p = (poly_base_size - fy1) * dx; - first = poly_base_size; - - 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_cur_cell(x_from >> poly_base_shift, ey1); - - if(ey1 != ey2) - { - p = poly_base_size * 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_base_size - first, x_to, first); - x_from = x_to; - - ey1 += incr; - set_cur_cell(x_from >> poly_base_shift, ey1); - } - } - render_hline(ey1, x_from, poly_base_size - first, x2, fy2); - } - - - //------------------------------------------------------------------------ - void outline_aa::move_to(int x, int y) - { - if(m_sorted) reset(); - set_cur_cell(x >> poly_base_shift, y >> poly_base_shift); - m_cur_x = x; - m_cur_y = y; - } - - - - //------------------------------------------------------------------------ - void outline_aa::line_to(int x, int y) - { - render_line(m_cur_x, m_cur_y, x, y); - m_cur_x = x; - m_cur_y = y; - m_sorted = false; - } - - - //------------------------------------------------------------------------ - enum - { - qsort_threshold = 9 - }; - - - //------------------------------------------------------------------------ - template static inline void swap_cells(T* a, T* b) - { - T temp = *a; - *a = *b; - *b = temp; - } - - //------------------------------------------------------------------------ - template static inline bool less_than(T* a, T* b) - { - return (*a)->packed_coord < (*b)->packed_coord; - } - - - - //------------------------------------------------------------------------ - void outline_aa::qsort_cells(cell_aa** start, unsigned num) - { - cell_aa** stack[80]; - cell_aa*** top; - cell_aa** limit; - cell_aa** base; - - limit = start + num; - base = start; - top = stack; - - for (;;) - { - int len = int(limit - base); - - cell_aa** i; - cell_aa** j; - cell_aa** 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(less_than(j, i)) - { - swap_cells(i, j); - } - - if(less_than(base, i)) - { - swap_cells(base, i); - } - - if(less_than(j, base)) - { - swap_cells(base, j); - } - - for(;;) - { - do i++; while( less_than(i, base) ); - do j--; while( less_than(base, j) ); - - 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(; less_than(j + 1, j); j--) - { - swap_cells(j + 1, j); - if (j == base) - { - break; - } - } - } - if(top > stack) - { - top -= 2; - base = top[0]; - limit = top[1]; - } - else - { - break; - } - } - } - } - - - - - - //------------------------------------------------------------------------ - void outline_aa::sort_cells() - { - if(m_num_cells == 0) return; - if(m_num_cells > m_sorted_size) - { - delete [] m_sorted_cells; - m_sorted_size = m_num_cells; - m_sorted_cells = new cell_aa* [m_num_cells + 1]; - } - - cell_aa** sorted_ptr = m_sorted_cells; - cell_aa** block_ptr = m_cells; - cell_aa* cell_ptr; - - unsigned nb = m_num_cells >> cell_block_shift; - unsigned i; - - while(nb--) - { - cell_ptr = *block_ptr++; - i = cell_block_size; - while(i--) - { - *sorted_ptr++ = cell_ptr++; - } - } - - cell_ptr = *block_ptr++; - i = m_num_cells & cell_block_mask; - while(i--) - { - *sorted_ptr++ = cell_ptr++; - } - m_sorted_cells[m_num_cells] = 0; - qsort_cells(m_sorted_cells, m_num_cells); - m_min_y = m_sorted_cells[0]->y; - m_max_y = m_sorted_cells[m_num_cells - 1]->y; - } - - - - - //------------------------------------------------------------------------ - const cell_aa* const* outline_aa::cells() - { - //Perform sort only the first time. - if(!m_sorted) - { - add_cur_cell(); - sort_cells(); - m_sorted = true; - } - return m_sorted_cells; - } - - - - - -} - - - - - diff --git a/src/libs/agg/src/agg_rounded_rect.cpp b/src/libs/agg/src/agg_rounded_rect.cpp index bc677a3295..bebc063628 100644 --- a/src/libs/agg/src/agg_rounded_rect.cpp +++ b/src/libs/agg/src/agg_rounded_rect.cpp @@ -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. diff --git a/src/libs/agg/src/agg_sqrt_tables.cpp b/src/libs/agg/src/agg_sqrt_tables.cpp index 9d176b39e3..5b3827c931 100644 --- a/src/libs/agg/src/agg_sqrt_tables.cpp +++ b/src/libs/agg/src/agg_sqrt_tables.cpp @@ -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. diff --git a/src/libs/agg/src/agg_trans_affine.cpp b/src/libs/agg/src/agg_trans_affine.cpp index 7382d27729..4c8bba1997 100644 --- a/src/libs/agg/src/agg_trans_affine.cpp +++ b/src/libs/agg/src/agg_trans_affine.cpp @@ -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. diff --git a/src/libs/agg/src/agg_trans_double_path.cpp b/src/libs/agg/src/agg_trans_double_path.cpp index ccc3f61ee5..cd40c7f586 100644 --- a/src/libs/agg/src/agg_trans_double_path.cpp +++ b/src/libs/agg/src/agg_trans_double_path.cpp @@ -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. @@ -101,6 +101,7 @@ namespace agg double dist; double d; + vertices.close(false); if(vertices.size() > 2) { if(vertices[vertices.size() - 2].dist * 10.0 < @@ -118,7 +119,6 @@ namespace agg } dist = 0; - vertices.close(false); for(i = 0; i < vertices.size(); i++) { vertex_dist& v = vertices[i]; @@ -228,7 +228,7 @@ namespace agg } else { - i = (unsigned)floor(*x * kindex); + i = unsigned(*x * kindex); j = i + 1; dd = vertices[j].dist - vertices[i].dist; d = ((*x * kindex) - i) * dd; diff --git a/src/libs/agg/src/agg_trans_single_path.cpp b/src/libs/agg/src/agg_trans_single_path.cpp index d7a34fe85a..2120fc9b9b 100644 --- a/src/libs/agg/src/agg_trans_single_path.cpp +++ b/src/libs/agg/src/agg_trans_single_path.cpp @@ -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. @@ -70,6 +70,7 @@ namespace agg double dist; double d; + m_src_vertices.close(false); if(m_src_vertices.size() > 2) { if(m_src_vertices[m_src_vertices.size() - 2].dist * 10.0 < @@ -87,7 +88,6 @@ namespace agg } dist = 0.0; - m_src_vertices.close(false); for(i = 0; i < m_src_vertices.size(); i++) { vertex_dist& v = m_src_vertices[i]; @@ -180,7 +180,7 @@ namespace agg } else { - i = (unsigned)floor(*x * m_kindex); + i = unsigned(*x * m_kindex); j = i + 1; dd = m_src_vertices[j].dist - m_src_vertices[i].dist; d = ((*x * m_kindex) - i) * dd; diff --git a/src/libs/agg/src/agg_trans_warp_magnifier.cpp b/src/libs/agg/src/agg_trans_warp_magnifier.cpp index 60b383de0b..99ee2b8a22 100644 --- a/src/libs/agg/src/agg_trans_warp_magnifier.cpp +++ b/src/libs/agg/src/agg_trans_warp_magnifier.cpp @@ -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. diff --git a/src/libs/agg/src/agg_vcgen_bspline.cpp b/src/libs/agg/src/agg_vcgen_bspline.cpp index b0d00bdf93..4a0be6693e 100644 --- a/src/libs/agg/src/agg_vcgen_bspline.cpp +++ b/src/libs/agg/src/agg_vcgen_bspline.cpp @@ -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. @@ -47,13 +47,13 @@ namespace agg m_status = initial; if(is_move_to(cmd)) { - m_src_vertices.modify_last(point_type(x, y)); + m_src_vertices.modify_last(point_d(x, y)); } else { if(is_vertex(cmd)) { - m_src_vertices.add(point_type(x, y)); + m_src_vertices.add(point_d(x, y)); } else { @@ -114,6 +114,7 @@ namespace agg m_spline_x.prepare(); m_spline_y.prepare(); } + m_status = ready; } diff --git a/src/libs/agg/src/agg_vcgen_contour.cpp b/src/libs/agg/src/agg_vcgen_contour.cpp index 293ac5bd2c..a6a99405ad 100644 --- a/src/libs/agg/src/agg_vcgen_contour.cpp +++ b/src/libs/agg/src/agg_vcgen_contour.cpp @@ -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. @@ -25,16 +25,10 @@ namespace agg //------------------------------------------------------------------------ vcgen_contour::vcgen_contour() : + m_stroker(), + m_width(1), m_src_vertices(), m_out_vertices(), - m_width(1.0), - m_line_join(bevel_join), - m_inner_line_join(miter_join_revert), - m_approx_scale(1.0), - m_abs_width(1.0), - m_signed_width(1.0), - m_miter_limit(4.0), - m_inner_miter_limit(1.0 + 1.0/64.0), m_status(initial), m_src_vertex(0), m_closed(0), @@ -43,26 +37,15 @@ namespace agg { } - //------------------------------------------------------------------------ void vcgen_contour::remove_all() { m_src_vertices.remove_all(); m_closed = 0; m_orientation = 0; - m_abs_width = fabs(m_width); - m_signed_width = m_width; m_status = initial; } - - //------------------------------------------------------------------------ - void vcgen_contour::miter_limit_theta(double t) - { - m_miter_limit = 1.0 / sin(t * 0.5) ; - } - - //------------------------------------------------------------------------ void vcgen_contour::add_vertex(double x, double y, unsigned cmd) { @@ -91,14 +74,12 @@ namespace agg } } - //------------------------------------------------------------------------ void vcgen_contour::rewind(unsigned) { if(m_status == initial) { m_src_vertices.close(true); - m_signed_width = m_width; if(m_auto_detect) { if(!is_oriented(m_orientation)) @@ -110,14 +91,13 @@ namespace agg } if(is_oriented(m_orientation)) { - m_signed_width = is_ccw(m_orientation) ? m_width : -m_width; + m_stroker.width(is_ccw(m_orientation) ? m_width : -m_width); } } m_status = ready; m_src_vertex = 0; } - //------------------------------------------------------------------------ unsigned vcgen_contour::vertex(double* x, double* y) { @@ -146,18 +126,12 @@ namespace agg m_status = end_poly; break; } - stroke_calc_join(m_out_vertices, - m_src_vertices.prev(m_src_vertex), - m_src_vertices.curr(m_src_vertex), - m_src_vertices.next(m_src_vertex), - m_src_vertices.prev(m_src_vertex).dist, - m_src_vertices.curr(m_src_vertex).dist, - m_signed_width, - m_line_join, - m_inner_line_join, - m_miter_limit, - m_inner_miter_limit, - m_approx_scale); + m_stroker.calc_join(m_out_vertices, + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.prev(m_src_vertex).dist, + m_src_vertices.curr(m_src_vertex).dist); ++m_src_vertex; m_status = out_vertices; m_out_vertex = 0; @@ -169,7 +143,7 @@ namespace agg } else { - const point_type& c = m_out_vertices[m_out_vertex++]; + const point_d& c = m_out_vertices[m_out_vertex++]; *x = c.x; *y = c.y; return cmd; diff --git a/src/libs/agg/src/agg_vcgen_dash.cpp b/src/libs/agg/src/agg_vcgen_dash.cpp index a9288ced60..129505786c 100644 --- a/src/libs/agg/src/agg_vcgen_dash.cpp +++ b/src/libs/agg/src/agg_vcgen_dash.cpp @@ -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. diff --git a/src/libs/agg/src/agg_vcgen_markers_term.cpp b/src/libs/agg/src/agg_vcgen_markers_term.cpp index 141116163c..3374ab5e82 100644 --- a/src/libs/agg/src/agg_vcgen_markers_term.cpp +++ b/src/libs/agg/src/agg_vcgen_markers_term.cpp @@ -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. @@ -73,9 +73,9 @@ namespace agg //------------------------------------------------------------------------ - void vcgen_markers_term::rewind(unsigned id) + void vcgen_markers_term::rewind(unsigned path_id) { - m_curr_id = id * 2; + m_curr_id = path_id * 2; m_curr_idx = m_curr_id; } diff --git a/src/libs/agg/src/agg_vcgen_smooth_poly1.cpp b/src/libs/agg/src/agg_vcgen_smooth_poly1.cpp index 79ae34dee4..ff7d488d39 100644 --- a/src/libs/agg/src/agg_vcgen_smooth_poly1.cpp +++ b/src/libs/agg/src/agg_vcgen_smooth_poly1.cpp @@ -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. diff --git a/src/libs/agg/src/agg_vcgen_stroke.cpp b/src/libs/agg/src/agg_vcgen_stroke.cpp index 0e7ee6ac00..2dae3e122b 100644 --- a/src/libs/agg/src/agg_vcgen_stroke.cpp +++ b/src/libs/agg/src/agg_vcgen_stroke.cpp @@ -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. @@ -25,16 +25,10 @@ namespace agg //------------------------------------------------------------------------ vcgen_stroke::vcgen_stroke() : + m_stroker(), m_src_vertices(), m_out_vertices(), - m_width(0.5), - m_miter_limit(4.0), - m_inner_miter_limit(1.0 + 1.0/64.0), - m_approx_scale(1.0), m_shorten(0.0), - m_line_cap(butt_cap), - m_line_join(miter_join), - m_inner_line_join(miter_join_revert), m_closed(0), m_status(initial), m_src_vertex(0), @@ -42,14 +36,6 @@ namespace agg { } - - //------------------------------------------------------------------------ - void vcgen_stroke::miter_limit_theta(double t) - { - m_miter_limit = 1.0 / sin(t * 0.5) ; - } - - //------------------------------------------------------------------------ void vcgen_stroke::remove_all() { @@ -80,7 +66,6 @@ namespace agg } } - //------------------------------------------------------------------------ void vcgen_stroke::rewind(unsigned) { @@ -120,13 +105,10 @@ namespace agg break; case cap1: - stroke_calc_cap(m_out_vertices, - m_src_vertices[0], - m_src_vertices[1], - m_src_vertices[0].dist, - m_line_cap, - m_width, - m_approx_scale); + m_stroker.calc_cap(m_out_vertices, + m_src_vertices[0], + m_src_vertices[1], + m_src_vertices[0].dist); m_src_vertex = 1; m_prev_status = outline1; m_status = out_vertices; @@ -134,13 +116,10 @@ namespace agg break; case cap2: - stroke_calc_cap(m_out_vertices, - m_src_vertices[m_src_vertices.size() - 1], - m_src_vertices[m_src_vertices.size() - 2], - m_src_vertices[m_src_vertices.size() - 2].dist, - m_line_cap, - m_width, - m_approx_scale); + m_stroker.calc_cap(m_out_vertices, + m_src_vertices[m_src_vertices.size() - 1], + m_src_vertices[m_src_vertices.size() - 2], + m_src_vertices[m_src_vertices.size() - 2].dist); m_prev_status = outline2; m_status = out_vertices; m_out_vertex = 0; @@ -164,18 +143,12 @@ namespace agg break; } } - stroke_calc_join(m_out_vertices, - m_src_vertices.prev(m_src_vertex), - m_src_vertices.curr(m_src_vertex), - m_src_vertices.next(m_src_vertex), - m_src_vertices.prev(m_src_vertex).dist, - m_src_vertices.curr(m_src_vertex).dist, - m_width, - m_line_join, - m_inner_line_join, - m_miter_limit, - m_inner_miter_limit, - m_approx_scale); + m_stroker.calc_join(m_out_vertices, + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.prev(m_src_vertex).dist, + m_src_vertices.curr(m_src_vertex).dist); ++m_src_vertex; m_prev_status = m_status; m_status = out_vertices; @@ -195,18 +168,12 @@ namespace agg } --m_src_vertex; - stroke_calc_join(m_out_vertices, - m_src_vertices.next(m_src_vertex), - m_src_vertices.curr(m_src_vertex), - m_src_vertices.prev(m_src_vertex), - m_src_vertices.curr(m_src_vertex).dist, - m_src_vertices.prev(m_src_vertex).dist, - m_width, - m_line_join, - m_inner_line_join, - m_miter_limit, - m_inner_miter_limit, - m_approx_scale); + m_stroker.calc_join(m_out_vertices, + m_src_vertices.next(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex).dist, + m_src_vertices.prev(m_src_vertex).dist); m_prev_status = m_status; m_status = out_vertices; @@ -220,7 +187,7 @@ namespace agg } else { - const point_type& c = m_out_vertices[m_out_vertex++]; + const point_d& c = m_out_vertices[m_out_vertex++]; *x = c.x; *y = c.y; return cmd; diff --git a/src/libs/agg/src/agg_vpgen_clip_polygon.cpp b/src/libs/agg/src/agg_vpgen_clip_polygon.cpp index affa267e99..4524526017 100644 --- a/src/libs/agg/src/agg_vpgen_clip_polygon.cpp +++ b/src/libs/agg/src/agg_vpgen_clip_polygon.cpp @@ -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. diff --git a/src/libs/agg/src/agg_vpgen_clip_polyline.cpp b/src/libs/agg/src/agg_vpgen_clip_polyline.cpp index b6d7b3b310..6840803a98 100644 --- a/src/libs/agg/src/agg_vpgen_clip_polyline.cpp +++ b/src/libs/agg/src/agg_vpgen_clip_polyline.cpp @@ -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. @@ -13,19 +13,17 @@ // http://www.antigrain.com //---------------------------------------------------------------------------- -#include #include "agg_vpgen_clip_polyline.h" +#include "agg_clip_liang_barsky.h" namespace agg { - static double clip_epsilon = 1e-10; - - //---------------------------------------------------------------------------- void vpgen_clip_polyline::reset() { m_vertex = 0; m_num_vertices = 0; + m_move_to = false; } //---------------------------------------------------------------------------- @@ -33,99 +31,38 @@ namespace agg { m_vertex = 0; m_num_vertices = 0; - m_f1 = clipping_flags(x, y); - if(m_f1 == 0) - { - m_x[0] = x; - m_y[0] = y; - m_cmd[0] = path_cmd_move_to; - m_num_vertices = 1; - } m_x1 = x; m_y1 = y; - } - - - //---------------------------------------------------------------------------- - bool vpgen_clip_polyline::move_point(double& x, double& y, unsigned& flags) - { - double bound; - - if(flags & (clip_x1 | clip_x2)) - { - bound = (flags & clip_x1) ? m_clip_box.x1 : m_clip_box.x2; - y = (bound - m_x1) * (m_y2 - m_y1) / (m_x2 - m_x1) + m_y1; - x = bound; - flags = clipping_flags_y(y); - } - if(fabs(m_y2 - m_y1) < clip_epsilon && fabs(m_x2 - m_x1) < clip_epsilon) - { - return false; - } - if(flags & (clip_y1 | clip_y2)) - { - bound = (flags & clip_y1) ? m_clip_box.y1 : m_clip_box.y2; - x = (bound - m_y1) * (m_x2 - m_x1) / (m_y2 - m_y1) + m_x1; - y = bound; - } - flags = 0; - return true; + m_move_to = true; } //---------------------------------------------------------------------------- - void vpgen_clip_polyline::clip_line_segment() + void vpgen_clip_polyline::line_to(double x, double y) { - if((m_f1 & m_f2) == 0) + double x2 = x; + double y2 = y; + unsigned flags = clip_line_segment(&m_x1, &m_y1, &x2, &y2, m_clip_box); + + m_vertex = 0; + m_num_vertices = 0; + if((flags & 4) == 0) { - if(m_f1) - { - if(!move_point(m_x1, m_y1, m_f1)) return; - if(m_f1) return; + if((flags & 1) != 0 || m_move_to) + { m_x[0] = m_x1; m_y[0] = m_y1; m_cmd[0] = path_cmd_move_to; m_num_vertices = 1; } - if(m_f2) - { // Move Point 2 - if(!move_point(m_x2, m_y2, m_f2)) return; - } - m_x[m_num_vertices] = m_x2; - m_y[m_num_vertices] = m_y2; + m_x[m_num_vertices] = x2; + m_y[m_num_vertices] = y2; m_cmd[m_num_vertices++] = path_cmd_line_to; + m_move_to = (flags & 2) != 0; } - } - - - - //---------------------------------------------------------------------------- - void vpgen_clip_polyline::line_to(double x, double y) - { - m_vertex = 0; - m_num_vertices = 0; - unsigned f = m_f2 = clipping_flags(m_x2 = x, m_y2 = y); - - if(m_f2 == m_f1) - { - if(m_f2 == 0) - { - m_x[0] = x; - m_y[0] = y; - m_cmd[0] = path_cmd_line_to; - m_num_vertices = 1; - } - } - else - { - clip_line_segment(); - } - - m_f1 = f; m_x1 = x; m_y1 = y; } - //---------------------------------------------------------------------------- unsigned vpgen_clip_polyline::vertex(double* x, double* y) { @@ -137,6 +74,4 @@ namespace agg } return path_cmd_stop; } - - } diff --git a/src/libs/agg/src/agg_vpgen_segmentator.cpp b/src/libs/agg/src/agg_vpgen_segmentator.cpp index 77fc3062be..49a45b6b13 100644 --- a/src/libs/agg/src/agg_vpgen_segmentator.cpp +++ b/src/libs/agg/src/agg_vpgen_segmentator.cpp @@ -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. diff --git a/src/libs/agg/src/ctrl/agg_bezier_ctrl.cpp b/src/libs/agg/src/ctrl/agg_bezier_ctrl.cpp deleted file mode 100644 index dfbd7138e5..0000000000 --- a/src/libs/agg/src/ctrl/agg_bezier_ctrl.cpp +++ /dev/null @@ -1,199 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes bezier_ctrl_impl, bezier_ctrl -// -//---------------------------------------------------------------------------- - -#include -#include -#include "ctrl/agg_bezier_ctrl.h" - -namespace agg -{ - - //------------------------------------------------------------------------ - bezier_ctrl_impl::bezier_ctrl_impl() : - ctrl(0,0,1,1,false), - m_stroke(m_curve), - m_poly(4, 5.0), - m_idx(0) - { - m_poly.in_polygon_check(false); - m_poly.xn(0) = 100.0; - m_poly.yn(0) = 0.0; - m_poly.xn(1) = 100.0; - m_poly.yn(1) = 50.0; - m_poly.xn(2) = 50.0; - m_poly.yn(2) = 100.0; - m_poly.xn(3) = 0.0; - m_poly.yn(3) = 100.0; - } - - - //------------------------------------------------------------------------ - void bezier_ctrl_impl::curve(double x1, double y1, - double x2, double y2, - double x3, double y3, - double x4, double y4) - { - m_poly.xn(0) = x1; - m_poly.yn(0) = y1; - m_poly.xn(1) = x2; - m_poly.yn(1) = y2; - m_poly.xn(2) = x3; - m_poly.yn(2) = y3; - m_poly.xn(3) = x4; - m_poly.yn(3) = y4; - curve(); - } - - //------------------------------------------------------------------------ - curve4& bezier_ctrl_impl::curve() - { - m_curve.init(m_poly.xn(0), m_poly.yn(0), - m_poly.xn(1), m_poly.yn(1), - m_poly.xn(2), m_poly.yn(2), - m_poly.xn(3), m_poly.yn(3)); - return m_curve; - } - - //------------------------------------------------------------------------ - void bezier_ctrl_impl::rewind(unsigned idx) - { - m_idx = idx; - - switch(idx) - { - default: - case 0: // Control line 1 - m_curve.init(m_poly.xn(0), m_poly.yn(0), - (m_poly.xn(0) + m_poly.xn(1)) * 0.5, - (m_poly.yn(0) + m_poly.yn(1)) * 0.5, - (m_poly.xn(0) + m_poly.xn(1)) * 0.5, - (m_poly.yn(0) + m_poly.yn(1)) * 0.5, - m_poly.xn(1), m_poly.yn(1)); - m_stroke.rewind(0); - break; - - case 1: // Control line 2 - m_curve.init(m_poly.xn(2), m_poly.yn(2), - (m_poly.xn(2) + m_poly.xn(3)) * 0.5, - (m_poly.yn(2) + m_poly.yn(3)) * 0.5, - (m_poly.xn(2) + m_poly.xn(3)) * 0.5, - (m_poly.yn(2) + m_poly.yn(3)) * 0.5, - m_poly.xn(3), m_poly.yn(3)); - m_stroke.rewind(0); - break; - - case 2: // Curve itself - m_curve.init(m_poly.xn(0), m_poly.yn(0), - m_poly.xn(1), m_poly.yn(1), - m_poly.xn(2), m_poly.yn(2), - m_poly.xn(3), m_poly.yn(3)); - m_stroke.rewind(0); - break; - - case 3: // Point 1 - m_ellipse.init(m_poly.xn(0), m_poly.yn(0), point_radius(), point_radius(), 20); - m_ellipse.rewind(0); - break; - - case 4: // Point 2 - m_ellipse.init(m_poly.xn(1), m_poly.yn(1), point_radius(), point_radius(), 20); - m_ellipse.rewind(0); - break; - - case 5: // Point 3 - m_ellipse.init(m_poly.xn(2), m_poly.yn(2), point_radius(), point_radius(), 20); - m_ellipse.rewind(0); - break; - - case 6: // Point 4 - m_ellipse.init(m_poly.xn(3), m_poly.yn(3), point_radius(), point_radius(), 20); - m_ellipse.rewind(0); - break; - } - } - - - //------------------------------------------------------------------------ - unsigned bezier_ctrl_impl::vertex(double* x, double* y) - { - unsigned cmd = path_cmd_stop; - switch(m_idx) - { - case 0: - case 1: - case 2: - cmd = m_stroke.vertex(x, y); - break; - - case 3: - case 4: - case 5: - case 6: - case 7: - cmd = m_ellipse.vertex(x, y); - break; - } - - if(!is_stop(cmd)) - { - transform_xy(x, y); - } - return cmd; - } - - - - //------------------------------------------------------------------------ - bool bezier_ctrl_impl::in_rect(double x, double y) const - { - return false; - } - - - //------------------------------------------------------------------------ - bool bezier_ctrl_impl::on_mouse_button_down(double x, double y) - { - inverse_transform_xy(&x, &y); - return m_poly.on_mouse_button_down(x, y); - } - - - //------------------------------------------------------------------------ - bool bezier_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) - { - inverse_transform_xy(&x, &y); - return m_poly.on_mouse_move(x, y, button_flag); - } - - - //------------------------------------------------------------------------ - bool bezier_ctrl_impl::on_mouse_button_up(double x, double y) - { - return m_poly.on_mouse_button_up(x, y); - } - - - //------------------------------------------------------------------------ - bool bezier_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) - { - return m_poly.on_arrow_keys(left, right, down, up); - } - -} - diff --git a/src/libs/agg/src/ctrl/agg_cbox_ctrl.cpp b/src/libs/agg/src/ctrl/agg_cbox_ctrl.cpp deleted file mode 100644 index b07870d95a..0000000000 --- a/src/libs/agg/src/ctrl/agg_cbox_ctrl.cpp +++ /dev/null @@ -1,214 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes rbox_ctrl_impl, rbox_ctrl -// -//---------------------------------------------------------------------------- - -#include -#include "ctrl/agg_cbox_ctrl.h" - - -namespace agg -{ - - //------------------------------------------------------------------------ - cbox_ctrl_impl::cbox_ctrl_impl(double x, double y, - const char* l, - bool flip_y) : - ctrl(x, y, x + 9.0 * 1.5, y + 9.0 * 1.5, flip_y), - m_text_thickness(1.5), - m_text_height(9.0), - m_text_width(0.0), - m_status(false), - m_text_poly(m_text) - { - label(l); - } - - - //------------------------------------------------------------------------ - void cbox_ctrl_impl::text_size(double h, double w) - { - m_text_width = w; - m_text_height = h; - } - - //------------------------------------------------------------------------ - void cbox_ctrl_impl::label(const char* l) - { - unsigned len = strlen(l); - if(len > 127) len = 127; - memcpy(m_label, l, len); - m_label[len] = 0; - } - - - //------------------------------------------------------------------------ - bool cbox_ctrl_impl::on_mouse_button_down(double x, double y) - { - inverse_transform_xy(&x, &y); - if(x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2) - { - m_status = !m_status; - return true; - } - return false; - } - - - //------------------------------------------------------------------------ - bool cbox_ctrl_impl::on_mouse_move(double, double, bool) - { - return false; - } - - //------------------------------------------------------------------------ - bool cbox_ctrl_impl::in_rect(double x, double y) const - { - inverse_transform_xy(&x, &y); - return x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2; - } - - //------------------------------------------------------------------------ - bool cbox_ctrl_impl::on_mouse_button_up(double, double) - { - return false; - } - - //------------------------------------------------------------------------ - bool cbox_ctrl_impl::on_arrow_keys(bool, bool, bool, bool) - { - return false; - } - - - //------------------------------------------------------------------------ - void cbox_ctrl_impl::rewind(unsigned idx) - { - m_idx = idx; - - double d2; - double t; - - switch(idx) - { - default: - case 0: // Border - m_vertex = 0; - m_vx[0] = m_x1; - m_vy[0] = m_y1; - m_vx[1] = m_x2; - m_vy[1] = m_y1; - m_vx[2] = m_x2; - m_vy[2] = m_y2; - m_vx[3] = m_x1; - m_vy[3] = m_y2; - m_vx[4] = m_x1 + m_text_thickness; - m_vy[4] = m_y1 + m_text_thickness; - m_vx[5] = m_x1 + m_text_thickness; - m_vy[5] = m_y2 - m_text_thickness; - m_vx[6] = m_x2 - m_text_thickness; - m_vy[6] = m_y2 - m_text_thickness; - m_vx[7] = m_x2 - m_text_thickness; - m_vy[7] = m_y1 + m_text_thickness; - break; - - case 1: // Text - m_text.text(m_label); - m_text.start_point(m_x1 + m_text_height * 2.0, m_y1 + m_text_height / 5.0); - m_text.size(m_text_height, m_text_width); - m_text_poly.width(m_text_thickness); - m_text_poly.line_join(round_join); - m_text_poly.line_cap(round_cap); - m_text_poly.rewind(0); - break; - - case 2: // Active item - m_vertex = 0; - d2 = (m_y2 - m_y1) / 2.0; - t = m_text_thickness * 1.5; - m_vx[0] = m_x1 + m_text_thickness; - m_vy[0] = m_y1 + m_text_thickness; - m_vx[1] = m_x1 + d2; - m_vy[1] = m_y1 + d2 - t; - m_vx[2] = m_x2 - m_text_thickness; - m_vy[2] = m_y1 + m_text_thickness; - m_vx[3] = m_x1 + d2 + t; - m_vy[3] = m_y1 + d2; - m_vx[4] = m_x2 - m_text_thickness; - m_vy[4] = m_y2 - m_text_thickness; - m_vx[5] = m_x1 + d2; - m_vy[5] = m_y1 + d2 + t; - m_vx[6] = m_x1 + m_text_thickness; - m_vy[6] = m_y2 - m_text_thickness; - m_vx[7] = m_x1 + d2 - t; - m_vy[7] = m_y1 + d2; - break; - - } - } - - - - - //------------------------------------------------------------------------ - unsigned cbox_ctrl_impl::vertex(double* x, double* y) - { - unsigned cmd = path_cmd_line_to; - switch(m_idx) - { - case 0: - if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; - if(m_vertex >= 8) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 1: - cmd = m_text_poly.vertex(x, y); - break; - - case 2: - if(m_status) - { - if(m_vertex == 0) cmd = path_cmd_move_to; - if(m_vertex >= 8) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - } - else - { - cmd = path_cmd_stop; - } - break; - - default: - cmd = path_cmd_stop; - break; - } - - if(!is_stop(cmd)) - { - transform_xy(x, y); - } - return cmd; - } -} - - - diff --git a/src/libs/agg/src/ctrl/agg_gamma_ctrl.cpp b/src/libs/agg/src/ctrl/agg_gamma_ctrl.cpp deleted file mode 100644 index 09f7448f2c..0000000000 --- a/src/libs/agg/src/ctrl/agg_gamma_ctrl.cpp +++ /dev/null @@ -1,433 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// class gamma_ctrl_impl -// -//---------------------------------------------------------------------------- - -#include -#include "agg_math.h" -#include "ctrl/agg_gamma_ctrl.h" - -namespace agg -{ - - //------------------------------------------------------------------------ - gamma_ctrl_impl::gamma_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y) : - ctrl(x1, y1, x2, y2, flip_y), - m_border_width(2.0), - m_border_extra(0.0), - m_curve_width(2.0), - m_grid_width(0.2), - m_text_thickness(1.5), - m_point_size(5.0), - m_text_height(9.0), - m_text_width(0.0), - m_xc1(x1), - m_yc1(y1), - m_xc2(x2), - m_yc2(y2 - m_text_height * 2.0), - m_xt1(x1), - m_yt1(y2 - m_text_height * 2.0), - m_xt2(x2), - m_yt2(y2), - m_curve_poly(m_gamma_spline), - m_text_poly(m_text), - m_idx(0), - m_vertex(0), - m_p1_active(true), - m_mouse_point(0), - m_pdx(0.0), - m_pdy(0.0) - { - calc_spline_box(); - } - - - //------------------------------------------------------------------------ - void gamma_ctrl_impl::calc_spline_box() - { - m_xs1 = m_xc1 + m_border_width; - m_ys1 = m_yc1 + m_border_width; - m_xs2 = m_xc2 - m_border_width; - m_ys2 = m_yc2 - m_border_width * 0.5; - } - - - //------------------------------------------------------------------------ - void gamma_ctrl_impl::calc_points() - { - double kx1, ky1, kx2, ky2; - m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); - m_xp1 = m_xs1 + (m_xs2 - m_xs1) * kx1 * 0.25; - m_yp1 = m_ys1 + (m_ys2 - m_ys1) * ky1 * 0.25; - m_xp2 = m_xs2 - (m_xs2 - m_xs1) * kx2 * 0.25; - m_yp2 = m_ys2 - (m_ys2 - m_ys1) * ky2 * 0.25; - } - - - //------------------------------------------------------------------------ - void gamma_ctrl_impl::calc_values() - { - double kx1, ky1, kx2, ky2; - - kx1 = (m_xp1 - m_xs1) * 4.0 / (m_xs2 - m_xs1); - ky1 = (m_yp1 - m_ys1) * 4.0 / (m_ys2 - m_ys1); - kx2 = (m_xs2 - m_xp2) * 4.0 / (m_xs2 - m_xs1); - ky2 = (m_ys2 - m_yp2) * 4.0 / (m_ys2 - m_ys1); - m_gamma_spline.values(kx1, ky1, kx2, ky2); - } - - - //------------------------------------------------------------------------ - void gamma_ctrl_impl::text_size(double h, double w) - { - m_text_width = w; - m_text_height = h; - m_yc2 = m_y2 - m_text_height * 2.0; - m_yt1 = m_y2 - m_text_height * 2.0; - calc_spline_box(); - } - - - //------------------------------------------------------------------------ - void gamma_ctrl_impl::border_width(double t, double extra) - { - m_border_width = t; - m_border_extra = extra; - calc_spline_box(); - } - - //------------------------------------------------------------------------ - void gamma_ctrl_impl::values(double kx1, double ky1, double kx2, double ky2) - { - m_gamma_spline.values(kx1, ky1, kx2, ky2); - } - - - //------------------------------------------------------------------------ - void gamma_ctrl_impl::values(double* kx1, double* ky1, double* kx2, double* ky2) const - { - m_gamma_spline.values(kx1, ky1, kx2, ky2); - } - - //------------------------------------------------------------------------ - void gamma_ctrl_impl::rewind(unsigned idx) - { - double kx1, ky1, kx2, ky2; - char tbuf[32]; - - m_idx = idx; - - switch(idx) - { - default: - - case 0: // Background - m_vertex = 0; - m_vx[0] = m_x1 - m_border_extra; - m_vy[0] = m_y1 - m_border_extra; - m_vx[1] = m_x2 + m_border_extra; - m_vy[1] = m_y1 - m_border_extra; - m_vx[2] = m_x2 + m_border_extra; - m_vy[2] = m_y2 + m_border_extra; - m_vx[3] = m_x1 - m_border_extra; - m_vy[3] = m_y2 + m_border_extra; - break; - - case 1: // Border - m_vertex = 0; - m_vx[0] = m_x1; - m_vy[0] = m_y1; - m_vx[1] = m_x2; - m_vy[1] = m_y1; - m_vx[2] = m_x2; - m_vy[2] = m_y2; - m_vx[3] = m_x1; - m_vy[3] = m_y2; - m_vx[4] = m_x1 + m_border_width; - m_vy[4] = m_y1 + m_border_width; - m_vx[5] = m_x1 + m_border_width; - m_vy[5] = m_y2 - m_border_width; - m_vx[6] = m_x2 - m_border_width; - m_vy[6] = m_y2 - m_border_width; - m_vx[7] = m_x2 - m_border_width; - m_vy[7] = m_y1 + m_border_width; - m_vx[8] = m_xc1 + m_border_width; - m_vy[8] = m_yc2 - m_border_width * 0.5; - m_vx[9] = m_xc2 - m_border_width; - m_vy[9] = m_yc2 - m_border_width * 0.5; - m_vx[10] = m_xc2 - m_border_width; - m_vy[10] = m_yc2 + m_border_width * 0.5; - m_vx[11] = m_xc1 + m_border_width; - m_vy[11] = m_yc2 + m_border_width * 0.5; - break; - - case 2: // Curve - m_gamma_spline.box(m_xs1, m_ys1, m_xs2, m_ys2); - m_curve_poly.width(m_curve_width); - m_curve_poly.rewind(0); - break; - - case 3: // Grid - m_vertex = 0; - m_vx[0] = m_xs1; - m_vy[0] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; - m_vx[1] = m_xs2; - m_vy[1] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; - m_vx[2] = m_xs2; - m_vy[2] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; - m_vx[3] = m_xs1; - m_vy[3] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; - m_vx[4] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; - m_vy[4] = m_ys1; - m_vx[5] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; - m_vy[5] = m_ys2; - m_vx[6] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; - m_vy[6] = m_ys2; - m_vx[7] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; - m_vy[7] = m_ys1; - calc_points(); - m_vx[8] = m_xs1; - m_vy[8] = m_yp1 - m_grid_width * 0.5; - m_vx[9] = m_xp1 - m_grid_width * 0.5; - m_vy[9] = m_yp1 - m_grid_width * 0.5; - m_vx[10] = m_xp1 - m_grid_width * 0.5; - m_vy[10] = m_ys1; - m_vx[11] = m_xp1 + m_grid_width * 0.5; - m_vy[11] = m_ys1; - m_vx[12] = m_xp1 + m_grid_width * 0.5; - m_vy[12] = m_yp1 + m_grid_width * 0.5; - m_vx[13] = m_xs1; - m_vy[13] = m_yp1 + m_grid_width * 0.5; - m_vx[14] = m_xs2; - m_vy[14] = m_yp2 + m_grid_width * 0.5; - m_vx[15] = m_xp2 + m_grid_width * 0.5; - m_vy[15] = m_yp2 + m_grid_width * 0.5; - m_vx[16] = m_xp2 + m_grid_width * 0.5; - m_vy[16] = m_ys2; - m_vx[17] = m_xp2 - m_grid_width * 0.5; - m_vy[17] = m_ys2; - m_vx[18] = m_xp2 - m_grid_width * 0.5; - m_vy[18] = m_yp2 - m_grid_width * 0.5; - m_vx[19] = m_xs2; - m_vy[19] = m_yp2 - m_grid_width * 0.5; - break; - - case 4: // Point1 - calc_points(); - if(m_p1_active) m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32); - else m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32); - break; - - case 5: // Point2 - calc_points(); - if(m_p1_active) m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32); - else m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32); - break; - - case 6: // Text - m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); - sprintf(tbuf, "%5.3f %5.3f %5.3f %5.3f", kx1, ky1, kx2, ky2); - m_text.text(tbuf); - m_text.size(m_text_height, m_text_width); - m_text.start_point(m_xt1 + m_border_width * 2.0, (m_yt1 + m_yt2) * 0.5 - m_text_height * 0.5); - m_text_poly.width(m_text_thickness); - m_text_poly.line_join(round_join); - m_text_poly.line_cap(round_cap); - m_text_poly.rewind(0); - break; - } - } - - - //------------------------------------------------------------------------ - unsigned gamma_ctrl_impl::vertex(double* x, double* y) - { - unsigned cmd = path_cmd_line_to; - switch(m_idx) - { - case 0: - if(m_vertex == 0) cmd = path_cmd_move_to; - if(m_vertex >= 4) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 1: - if(m_vertex == 0 || m_vertex == 4 || m_vertex == 8) cmd = path_cmd_move_to; - if(m_vertex >= 12) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 2: - cmd = m_curve_poly.vertex(x, y); - break; - - case 3: - if(m_vertex == 0 || - m_vertex == 4 || - m_vertex == 8 || - m_vertex == 14) cmd = path_cmd_move_to; - - if(m_vertex >= 20) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 4: // Point1 - case 5: // Point2 - cmd = m_ellipse.vertex(x, y); - break; - - case 6: - cmd = m_text_poly.vertex(x, y); - break; - - default: - cmd = path_cmd_stop; - break; - } - - if(!is_stop(cmd)) - { - transform_xy(x, y); - } - - return cmd; - } - - - - //------------------------------------------------------------------------ - bool gamma_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) - { - double kx1, ky1, kx2, ky2; - bool ret = false; - m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); - if(m_p1_active) - { - if(left) { kx1 -= 0.005; ret = true; } - if(right) { kx1 += 0.005; ret = true; } - if(down) { ky1 -= 0.005; ret = true; } - if(up) { ky1 += 0.005; ret = true; } - } - else - { - if(left) { kx2 += 0.005; ret = true; } - if(right) { kx2 -= 0.005; ret = true; } - if(down) { ky2 += 0.005; ret = true; } - if(up) { ky2 -= 0.005; ret = true; } - } - if(ret) - { - m_gamma_spline.values(kx1, ky1, kx2, ky2); - } - return ret; - } - - - - //------------------------------------------------------------------------ - void gamma_ctrl_impl::change_active_point() - { - m_p1_active = m_p1_active ? false : true; - } - - - - - //------------------------------------------------------------------------ - bool gamma_ctrl_impl::in_rect(double x, double y) const - { - inverse_transform_xy(&x, &y); - return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; - } - - - //------------------------------------------------------------------------ - bool gamma_ctrl_impl::on_mouse_button_down(double x, double y) - { - inverse_transform_xy(&x, &y); - calc_points(); - - if(calc_distance(x, y, m_xp1, m_yp1) <= m_point_size + 1) - { - m_mouse_point = 1; - m_pdx = m_xp1 - x; - m_pdy = m_yp1 - y; - m_p1_active = true; - return true; - } - - if(calc_distance(x, y, m_xp2, m_yp2) <= m_point_size + 1) - { - m_mouse_point = 2; - m_pdx = m_xp2 - x; - m_pdy = m_yp2 - y; - m_p1_active = false; - return true; - } - - return false; - } - - - //------------------------------------------------------------------------ - bool gamma_ctrl_impl::on_mouse_button_up(double, double) - { - if(m_mouse_point) - { - m_mouse_point = 0; - return true; - } - return false; - } - - - //------------------------------------------------------------------------ - bool gamma_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) - { - inverse_transform_xy(&x, &y); - if(!button_flag) - { - return on_mouse_button_up(x, y); - } - - if(m_mouse_point == 1) - { - m_xp1 = x + m_pdx; - m_yp1 = y + m_pdy; - calc_values(); - return true; - } - if(m_mouse_point == 2) - { - m_xp2 = x + m_pdx; - m_yp2 = y + m_pdy; - calc_values(); - return true; - } - return false; - } - - - -} - diff --git a/src/libs/agg/src/ctrl/agg_gamma_spline.cpp b/src/libs/agg/src/ctrl/agg_gamma_spline.cpp deleted file mode 100644 index 3e227195fc..0000000000 --- a/src/libs/agg/src/ctrl/agg_gamma_spline.cpp +++ /dev/null @@ -1,130 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// class gamma_spline -// -//---------------------------------------------------------------------------- - -#include "ctrl/agg_gamma_spline.h" - -namespace agg -{ - - //------------------------------------------------------------------------ - gamma_spline::gamma_spline() : - m_x1(0), m_y1(0), m_x2(10), m_y2(10), m_cur_x(0.0) - { - values(1.0, 1.0, 1.0, 1.0); - } - - - //------------------------------------------------------------------------ - double gamma_spline::y(double x) const - { - if(x < 0.0) x = 0.0; - if(x > 1.0) x = 1.0; - double val = m_spline.get(x); - if(val < 0.0) val = 0.0; - if(val > 1.0) val = 1.0; - return val; - } - - - - //------------------------------------------------------------------------ - void gamma_spline::values(double kx1, double ky1, double kx2, double ky2) - { - if(kx1 < 0.001) kx1 = 0.001; - if(kx1 > 1.999) kx1 = 1.999; - if(ky1 < 0.001) ky1 = 0.001; - if(ky1 > 1.999) ky1 = 1.999; - if(kx2 < 0.001) kx2 = 0.001; - if(kx2 > 1.999) kx2 = 1.999; - if(ky2 < 0.001) ky2 = 0.001; - if(ky2 > 1.999) ky2 = 1.999; - - m_x[0] = 0.0; - m_y[0] = 0.0; - m_x[1] = kx1 * 0.25; - m_y[1] = ky1 * 0.25; - m_x[2] = 1.0 - kx2 * 0.25; - m_y[2] = 1.0 - ky2 * 0.25; - m_x[3] = 1.0; - m_y[3] = 1.0; - - m_spline.init(4, m_x, m_y); - - int i; - for(i = 0; i < 256; i++) - { - m_gamma[i] = (unsigned char)(y(double(i) / 255.0) * 255.0); - } - } - - - //------------------------------------------------------------------------ - void gamma_spline::values(double* kx1, double* ky1, double* kx2, double* ky2) const - { - *kx1 = m_x[1] * 4.0; - *ky1 = m_y[1] * 4.0; - *kx2 = (1.0 - m_x[2]) * 4.0; - *ky2 = (1.0 - m_y[2]) * 4.0; - } - - - //------------------------------------------------------------------------ - void gamma_spline::box(double x1, double y1, double x2, double y2) - { - m_x1 = x1; - m_y1 = y1; - m_x2 = x2; - m_y2 = y2; - } - - - //------------------------------------------------------------------------ - void gamma_spline::rewind(unsigned) - { - m_cur_x = 0.0; - } - - - //------------------------------------------------------------------------ - unsigned gamma_spline::vertex(double* vx, double* vy) - { - if(m_cur_x == 0.0) - { - *vx = m_x1; - *vy = m_y1; - m_cur_x += 1.0 / (m_x2 - m_x1); - return path_cmd_move_to; - } - - if(m_cur_x > 1.0) - { - return path_cmd_stop; - } - - *vx = m_x1 + m_cur_x * (m_x2 - m_x1); - *vy = m_y1 + y(m_cur_x) * (m_y2 - m_y1); - - m_cur_x += 1.0 / (m_x2 - m_x1); - return path_cmd_line_to; - } - - - -} - diff --git a/src/libs/agg/src/ctrl/agg_polygon_ctrl.cpp b/src/libs/agg/src/ctrl/agg_polygon_ctrl.cpp deleted file mode 100644 index 6c6b858068..0000000000 --- a/src/libs/agg/src/ctrl/agg_polygon_ctrl.cpp +++ /dev/null @@ -1,337 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes polygon_ctrl_impl -// -//---------------------------------------------------------------------------- - -#include "ctrl/agg_polygon_ctrl.h" - -namespace agg -{ - - polygon_ctrl_impl::~polygon_ctrl_impl() - { - delete [] m_polygon; - } - - - polygon_ctrl_impl::polygon_ctrl_impl(unsigned np, double point_radius) : - ctrl(0, 0, 1, 1, false), - m_polygon(new double[np * 2]), - m_num_points(np), - m_node(-1), - m_edge(-1), - m_vs(m_polygon, m_num_points, false), - m_stroke(m_vs), - m_point_radius(point_radius), - m_status(0), - m_dx(0.0), - m_dy(0.0) - { - m_stroke.width(1.0); - } - - - void polygon_ctrl_impl::rewind(unsigned) - { - m_status = 0; - m_stroke.rewind(0); - } - - unsigned polygon_ctrl_impl::vertex(double* x, double* y) - { - unsigned cmd = path_cmd_stop; - double r = m_point_radius; - if(m_status == 0) - { - cmd = m_stroke.vertex(x, y); - if(!is_stop(cmd)) - { - transform_xy(x, y); - return cmd; - } - if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; - m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); - ++m_status; - } - cmd = m_ellipse.vertex(x, y); - if(!is_stop(cmd)) - { - transform_xy(x, y); - return cmd; - } - if(m_status >= m_num_points) return path_cmd_stop; - if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; - m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); - ++m_status; - cmd = m_ellipse.vertex(x, y); - if(!is_stop(cmd)) - { - transform_xy(x, y); - } - return cmd; - } - - - bool polygon_ctrl_impl::check_edge(unsigned i, double x, double y) const - { - bool ret = false; - - unsigned n1 = i; - unsigned n2 = (i + m_num_points - 1) % m_num_points; - double x1 = xn(n1); - double y1 = yn(n1); - double x2 = xn(n2); - double y2 = yn(n2); - - double dx = x2 - x1; - double dy = y2 - y1; - - if(sqrt(dx*dx + dy*dy) > 0.0000001) - { - double x3 = x; - double y3 = y; - double x4 = x3 - dy; - double y4 = y3 + dx; - - double den = (y4-y3) * (x2-x1) - (x4-x3) * (y2-y1); - double u1 = ((x4-x3) * (y1-y3) - (y4-y3) * (x1-x3)) / den; - - double xi = x1 + u1 * (x2 - x1); - double yi = y1 + u1 * (y2 - y1); - - dx = xi - x; - dy = yi - y; - - if (u1 > 0.0 && u1 < 1.0 && sqrt(dx*dx + dy*dy) <= m_point_radius) - { - ret = true; - } - } - return ret; - } - - - - bool polygon_ctrl_impl::in_rect(double x, double y) const - { - return false; - } - - - bool polygon_ctrl_impl::on_mouse_button_down(double x, double y) - { - unsigned i; - bool ret = false; - m_node = -1; - m_edge = -1; - inverse_transform_xy(&x, &y); - for (i = 0; i < m_num_points; i++) - { - if(sqrt( (x-xn(i)) * (x-xn(i)) + (y-yn(i)) * (y-yn(i)) ) < m_point_radius) - { - m_dx = x - xn(i); - m_dy = y - yn(i); - m_node = int(i); - ret = true; - break; - } - } - - if(!ret) - { - for (i = 0; i < m_num_points; i++) - { - if(check_edge(i, x, y)) - { - m_dx = x; - m_dy = y; - m_edge = int(i); - ret = true; - break; - } - } - } - - if(!ret) - { - if(point_in_polygon(x, y)) - { - m_dx = x; - m_dy = y; - m_node = int(m_num_points); - ret = true; - } - } - return ret; - } - - - bool polygon_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) - { - bool ret = false; - double dx; - double dy; - inverse_transform_xy(&x, &y); - if(m_node == int(m_num_points)) - { - dx = x - m_dx; - dy = y - m_dy; - unsigned i; - for(i = 0; i < m_num_points; i++) - { - xn(i) += dx; - yn(i) += dy; - } - m_dx = x; - m_dy = y; - ret = true; - } - else - { - if(m_edge >= 0) - { - unsigned n1 = m_edge; - unsigned n2 = (n1 + m_num_points - 1) % m_num_points; - dx = x - m_dx; - dy = y - m_dy; - xn(n1) += dx; - yn(n1) += dy; - xn(n2) += dx; - yn(n2) += dy; - m_dx = x; - m_dy = y; - ret = true; - } - else - { - if(m_node >= 0) - { - xn(m_node) = x - m_dx; - yn(m_node) = y - m_dy; - ret = true; - } - } - } - return ret; - } - - bool polygon_ctrl_impl::on_mouse_button_up(double x, double y) - { - bool ret = (m_node >= 0) || (m_edge >= 0); - m_node = -1; - m_edge = -1; - return ret; - } - - - bool polygon_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) - { - return false; - } - - - //======= Crossings Multiply algorithm of InsideTest ======================== - // - // By Eric Haines, 3D/Eye Inc, erich@eye.com - // - // This version is usually somewhat faster than the original published in - // Graphics Gems IV; by turning the division for testing the X axis crossing - // into a tricky multiplication test this part of the test became faster, - // which had the additional effect of making the test for "both to left or - // both to right" a bit slower for triangles than simply computing the - // intersection each time. The main increase is in triangle testing speed, - // which was about 15% faster; all other polygon complexities were pretty much - // the same as before. On machines where division is very expensive (not the - // case on the HP 9000 series on which I tested) this test should be much - // faster overall than the old code. Your mileage may (in fact, will) vary, - // depending on the machine and the test data, but in general I believe this - // code is both shorter and faster. This test was inspired by unpublished - // Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson. - // Related work by Samosky is in: - // - // Samosky, Joseph, "SectionView: A system for interactively specifying and - // visualizing sections through three-dimensional medical image data", - // M.S. Thesis, Department of Electrical Engineering and Computer Science, - // Massachusetts Institute of Technology, 1993. - // - // Shoot a test ray along +X axis. The strategy is to compare vertex Y values - // to the testing point's Y and quickly discard edges which are entirely to one - // side of the test ray. Note that CONVEX and WINDING code can be added as - // for the CrossingsTest() code; it is left out here for clarity. - // - // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point - // _point_, returns 1 if inside, 0 if outside. - bool polygon_ctrl_impl::point_in_polygon(double tx, double ty) const - { - if(m_num_points < 3) return false; - if(!m_in_polygon_check) return false; - - unsigned j; - int yflag0, yflag1, inside_flag; - double vtx0, vty0, vtx1, vty1; - - vtx0 = xn(m_num_points - 1); - vty0 = yn(m_num_points - 1); - - // get test bit for above/below X axis - yflag0 = (vty0 >= ty); - - vtx1 = xn(0); - vty1 = yn(0); - - inside_flag = 0; - for (j = 1; j <= m_num_points; ++j) - { - yflag1 = (vty1 >= ty); - // Check if endpoints straddle (are on opposite sides) of X axis - // (i.e. the Y's differ); if so, +X ray could intersect this edge. - // The old test also checked whether the endpoints are both to the - // right or to the left of the test point. However, given the faster - // intersection point computation used below, this test was found to - // be a break-even proposition for most polygons and a loser for - // triangles (where 50% or more of the edges which survive this test - // will cross quadrants and so have to have the X intersection computed - // anyway). I credit Joseph Samosky with inspiring me to try dropping - // the "both left or both right" part of my code. - if (yflag0 != yflag1) - { - // Check intersection of pgon segment with +X ray. - // Note if >= point's X; if so, the ray hits it. - // The division operation is avoided for the ">=" test by checking - // the sign of the first vertex wrto the test point; idea inspired - // by Joseph Samosky's and Mark Haigh-Hutchinson's different - // polygon inclusion tests. - if ( ((vty1-ty) * (vtx0-vtx1) >= - (vtx1-tx) * (vty0-vty1)) == yflag1 ) - { - inside_flag ^= 1; - } - } - - // Move to the next pair of vertices, retaining info as possible. - yflag0 = yflag1; - vtx0 = vtx1; - vty0 = vty1; - - unsigned k = (j >= m_num_points) ? j - m_num_points : j; - vtx1 = xn(k); - vty1 = yn(k); - } - return inside_flag != 0; - } -} - diff --git a/src/libs/agg/src/ctrl/agg_rbox_ctrl.cpp b/src/libs/agg/src/ctrl/agg_rbox_ctrl.cpp deleted file mode 100644 index 425e467cee..0000000000 --- a/src/libs/agg/src/ctrl/agg_rbox_ctrl.cpp +++ /dev/null @@ -1,340 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes rbox_ctrl_impl, rbox_ctrl -// -//---------------------------------------------------------------------------- - -#include -#include "ctrl/agg_rbox_ctrl.h" - -namespace agg -{ - - //------------------------------------------------------------------------ - rbox_ctrl_impl::~rbox_ctrl_impl() - { - if(m_num_items) - { - char** item = m_items + m_num_items - 1; - while(m_num_items--) - { - delete *item; - --item; - } - } - } - - - //------------------------------------------------------------------------ - rbox_ctrl_impl::rbox_ctrl_impl(double x1, double y1, - double x2, double y2, bool flip_y) : - ctrl(x1, y1, x2, y2, flip_y), - m_border_width(1.0), - m_border_extra(0.0), - m_text_thickness(1.5), - m_text_height(9.0), - m_text_width(0.0), - m_num_items(0), - m_cur_item(-1), - m_ellipse_poly(m_ellipse), - m_text_poly(m_text), - m_idx(0), - m_vertex(0) - { - calc_rbox(); - } - - - //------------------------------------------------------------------------ - void rbox_ctrl_impl::calc_rbox() - { - m_xs1 = m_x1 + m_border_width; - m_ys1 = m_y1 + m_border_width; - m_xs2 = m_x2 - m_border_width; - m_ys2 = m_y2 - m_border_width; - } - - - //------------------------------------------------------------------------ - void rbox_ctrl_impl::add_item(const char* text) - { - if(m_num_items < 32) - { - m_items[m_num_items] = new char[strlen(text) + 1]; - strcpy(m_items[m_num_items], text); - m_num_items++; - } - } - - - //------------------------------------------------------------------------ - void rbox_ctrl_impl::border_width(double t, double extra) - { - m_border_width = t; - m_border_extra = extra; - calc_rbox(); - } - - - //------------------------------------------------------------------------ - void rbox_ctrl_impl::text_size(double h, double w) - { - m_text_width = w; - m_text_height = h; - } - - - - //------------------------------------------------------------------------ - void rbox_ctrl_impl::rewind(unsigned idx) - { - m_idx = idx; - m_dy = m_text_height * 2.0; - m_draw_item = 0; - - switch(idx) - { - default: - - case 0: // Background - m_vertex = 0; - m_vx[0] = m_x1 - m_border_extra; - m_vy[0] = m_y1 - m_border_extra; - m_vx[1] = m_x2 + m_border_extra; - m_vy[1] = m_y1 - m_border_extra; - m_vx[2] = m_x2 + m_border_extra; - m_vy[2] = m_y2 + m_border_extra; - m_vx[3] = m_x1 - m_border_extra; - m_vy[3] = m_y2 + m_border_extra; - break; - - case 1: // Border - m_vertex = 0; - m_vx[0] = m_x1; - m_vy[0] = m_y1; - m_vx[1] = m_x2; - m_vy[1] = m_y1; - m_vx[2] = m_x2; - m_vy[2] = m_y2; - m_vx[3] = m_x1; - m_vy[3] = m_y2; - m_vx[4] = m_x1 + m_border_width; - m_vy[4] = m_y1 + m_border_width; - m_vx[5] = m_x1 + m_border_width; - m_vy[5] = m_y2 - m_border_width; - m_vx[6] = m_x2 - m_border_width; - m_vy[6] = m_y2 - m_border_width; - m_vx[7] = m_x2 - m_border_width; - m_vy[7] = m_y1 + m_border_width; - break; - - case 2: // Text - m_text.text(m_items[0]); - m_text.start_point(m_xs1 + m_dy * 1.5, m_ys1 + m_dy / 2.0); - m_text.size(m_text_height, m_text_width); - m_text_poly.width(m_text_thickness); - m_text_poly.line_join(round_join); - m_text_poly.line_cap(round_cap); - m_text_poly.rewind(0); - break; - - case 3: // Inactive items - m_ellipse.init(m_xs1 + m_dy / 1.3, - m_ys1 + m_dy / 1.3, - m_text_height / 1.5, - m_text_height / 1.5, 32); - m_ellipse_poly.width(m_text_thickness); - m_ellipse_poly.rewind(0); - break; - - - case 4: // Active Item - if(m_cur_item >= 0) - { - m_ellipse.init(m_xs1 + m_dy / 1.3, - m_ys1 + m_dy * m_cur_item + m_dy / 1.3, - m_text_height / 2.0, - m_text_height / 2.0, 32); - m_ellipse.rewind(0); - } - break; - - } - } - - - //------------------------------------------------------------------------ - unsigned rbox_ctrl_impl::vertex(double* x, double* y) - { - unsigned cmd = path_cmd_line_to; - switch(m_idx) - { - case 0: - if(m_vertex == 0) cmd = path_cmd_move_to; - if(m_vertex >= 4) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 1: - if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; - if(m_vertex >= 8) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 2: - cmd = m_text_poly.vertex(x, y); - if(is_stop(cmd)) - { - m_draw_item++; - if(m_draw_item >= m_num_items) - { - break; - } - else - { - m_text.text(m_items[m_draw_item]); - m_text.start_point(m_xs1 + m_dy * 1.5, - m_ys1 + m_dy * (m_draw_item + 1) - m_dy / 2.0); - - m_text_poly.rewind(0); - cmd = m_text_poly.vertex(x, y); - } - } - break; - - case 3: - cmd = m_ellipse_poly.vertex(x, y); - if(is_stop(cmd)) - { - m_draw_item++; - if(m_draw_item >= m_num_items) - { - break; - } - else - { - m_ellipse.init(m_xs1 + m_dy / 1.3, - m_ys1 + m_dy * m_draw_item + m_dy / 1.3, - m_text_height / 1.5, - m_text_height / 1.5, 32); - m_ellipse_poly.rewind(0); - cmd = m_ellipse_poly.vertex(x, y); - } - } - break; - - - case 4: - if(m_cur_item >= 0) - { - cmd = m_ellipse.vertex(x, y); - } - else - { - cmd = path_cmd_stop; - } - break; - - default: - cmd = path_cmd_stop; - break; - } - - if(!is_stop(cmd)) - { - transform_xy(x, y); - } - - return cmd; - } - - - //------------------------------------------------------------------------ - bool rbox_ctrl_impl::in_rect(double x, double y) const - { - inverse_transform_xy(&x, &y); - return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; - } - - - - //------------------------------------------------------------------------ - bool rbox_ctrl_impl::on_mouse_button_down(double x, double y) - { - inverse_transform_xy(&x, &y); - unsigned i; - for(i = 0; i < m_num_items; i++) - { - double xp = m_xs1 + m_dy / 1.3; - double yp = m_ys1 + m_dy * i + m_dy / 1.3; - if(calc_distance(x, y, xp, yp) <= m_text_height / 1.5) - { - m_cur_item = int(i); - return true; - } - } - return false; - } - - - //------------------------------------------------------------------------ - bool rbox_ctrl_impl::on_mouse_move(double, double, bool) - { - return false; - } - - //------------------------------------------------------------------------ - bool rbox_ctrl_impl::on_mouse_button_up(double, double) - { - return false; - } - - //------------------------------------------------------------------------ - bool rbox_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) - { - if(m_cur_item >= 0) - { - if(up || right) - { - m_cur_item++; - if(m_cur_item >= int(m_num_items)) - { - m_cur_item = 0; - } - return true; - } - - if(down || left) - { - m_cur_item--; - if(m_cur_item < 0) - { - m_cur_item = m_num_items - 1; - } - return true; - } - } - return false; - } - - -} - - diff --git a/src/libs/agg/src/ctrl/agg_scale_ctrl.cpp b/src/libs/agg/src/ctrl/agg_scale_ctrl.cpp deleted file mode 100644 index bcc488f256..0000000000 --- a/src/libs/agg/src/ctrl/agg_scale_ctrl.cpp +++ /dev/null @@ -1,302 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes scale_ctrl_impl, scale_ctrl -// -//---------------------------------------------------------------------------- - -#include "ctrl/agg_scale_ctrl.h" - -namespace agg -{ - - //------------------------------------------------------------------------ - scale_ctrl_impl::scale_ctrl_impl(double x1, double y1, - double x2, double y2, bool flip_y) : - ctrl(x1, y1, x2, y2, flip_y), - m_border_thickness(1.0), - m_border_extra((y2 - y1) / 2), - m_pdx(0.0), - m_move_what(move_nothing), - m_value1(0.3), - m_value2(0.7), - m_min_d(0.01) - { - calc_box(); - } - - - //------------------------------------------------------------------------ - void scale_ctrl_impl::calc_box() - { - m_xs1 = m_x1 + m_border_thickness; - m_ys1 = m_y1 + m_border_thickness; - m_xs2 = m_x2 - m_border_thickness; - m_ys2 = m_y2 - m_border_thickness; - } - - - //------------------------------------------------------------------------ - void scale_ctrl_impl::border_thickness(double t, double extra) - { - m_border_thickness = t; - m_border_extra = extra; - calc_box(); - } - - - - //------------------------------------------------------------------------ - void scale_ctrl_impl::rewind(unsigned idx) - { - m_idx = idx; - - switch(idx) - { - default: - - case 0: // Background - m_vertex = 0; - m_vx[0] = m_x1 - m_border_extra; - m_vy[0] = m_y1 - m_border_extra; - m_vx[1] = m_x2 + m_border_extra; - m_vy[1] = m_y1 - m_border_extra; - m_vx[2] = m_x2 + m_border_extra; - m_vy[2] = m_y2 + m_border_extra; - m_vx[3] = m_x1 - m_border_extra; - m_vy[3] = m_y2 + m_border_extra; - break; - - case 1: // Border - m_vertex = 0; - m_vx[0] = m_x1; - m_vy[0] = m_y1; - m_vx[1] = m_x2; - m_vy[1] = m_y1; - m_vx[2] = m_x2; - m_vy[2] = m_y2; - m_vx[3] = m_x1; - m_vy[3] = m_y2; - m_vx[4] = m_x1 + m_border_thickness; - m_vy[4] = m_y1 + m_border_thickness; - m_vx[5] = m_x1 + m_border_thickness; - m_vy[5] = m_y2 - m_border_thickness; - m_vx[6] = m_x2 - m_border_thickness; - m_vy[6] = m_y2 - m_border_thickness; - m_vx[7] = m_x2 - m_border_thickness; - m_vy[7] = m_y1 + m_border_thickness; - break; - - case 2: // pointer1 - m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value1, - (m_ys1 + m_ys2) / 2.0, - m_y2 - m_y1, - m_y2 - m_y1, - 32); - m_ellipse.rewind(0); - break; - - case 3: // pointer2 - m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value2, - (m_ys1 + m_ys2) / 2.0, - m_y2 - m_y1, - m_y2 - m_y1, - 32); - m_ellipse.rewind(0); - break; - - case 4: // slider - m_vertex = 0; - m_vx[0] = m_xs1 + (m_xs2 - m_xs1) * m_value1; - m_vy[0] = m_y1 - m_border_extra / 2.0; - m_vx[1] = m_xs1 + (m_xs2 - m_xs1) * m_value2; - m_vy[1] = m_vy[0]; - m_vx[2] = m_vx[1]; - m_vy[2] = m_y2 + m_border_extra / 2.0; - m_vx[3] = m_vx[0]; - m_vy[3] = m_vy[2]; - break; - } - } - - - //------------------------------------------------------------------------ - unsigned scale_ctrl_impl::vertex(double* x, double* y) - { - unsigned cmd = path_cmd_line_to; - switch(m_idx) - { - case 0: - case 4: - if(m_vertex == 0) cmd = path_cmd_move_to; - if(m_vertex >= 4) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 1: - if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; - if(m_vertex >= 8) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 2: - case 3: - cmd = m_ellipse.vertex(x, y); - break; - - default: - cmd = path_cmd_stop; - break; - } - - if(!is_stop(cmd)) - { - transform_xy(x, y); - } - - return cmd; - } - - - - //------------------------------------------------------------------------ - bool scale_ctrl_impl::in_rect(double x, double y) const - { - inverse_transform_xy(&x, &y); - return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; - } - - - //------------------------------------------------------------------------ - bool scale_ctrl_impl::on_mouse_button_down(double x, double y) - { - inverse_transform_xy(&x, &y); - - double xp1 = m_xs1 + (m_xs2 - m_xs1) * m_value1; - double xp2 = m_xs1 + (m_xs2 - m_xs1) * m_value2; - double ys1 = m_y1 - m_border_extra / 2.0; - double ys2 = m_y2 + m_border_extra / 2.0; - double yp = (m_ys1 + m_ys2) / 2.0; - - if(x > xp1 && y > ys1 && x < xp2 && y < ys2) - { - m_pdx = xp1 - x; - m_move_what = move_slider; - return true; - } - - if(x < xp1 && calc_distance(x, y, xp1, yp) <= m_y2 - m_y1) - { - m_pdx = xp1 - x; - m_move_what = move_value1; - return true; - } - - if(x > xp2 && calc_distance(x, y, xp2, yp) <= m_y2 - m_y1) - { - m_pdx = xp2 - x; - m_move_what = move_value2; - return true; - } - - - return false; - } - - - //------------------------------------------------------------------------ - bool scale_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) - { - inverse_transform_xy(&x, &y); - if(!button_flag) - { - return on_mouse_button_up(x, y); - } - - double xp = x + m_pdx; - double dv; - - switch(m_move_what) - { - case move_value1: - m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1); - if(m_value1 < 0.0) m_value1 = 0.0; - if(m_value1 > m_value2 - m_min_d) m_value1 = m_value2 - m_min_d; - return true; - - case move_value2: - m_value2 = (xp - m_xs1) / (m_xs2 - m_xs1); - if(m_value2 > 1.0) m_value2 = 1.0; - if(m_value2 < m_value1 + m_min_d) m_value2 = m_value1 + m_min_d; - return true; - - case move_slider: - dv = m_value2 - m_value1; - m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1); - m_value2 = m_value1 + dv; - if(m_value1 < 0.0) - { - dv = m_value2 - m_value1; - m_value1 = 0.0; - m_value2 = m_value1 + dv; - } - if(m_value2 > 1.0) - { - dv = m_value2 - m_value1; - m_value2 = 1.0; - m_value1 = m_value2 - dv; - } - return true; - } - - return false; - } - - - //------------------------------------------------------------------------ - bool scale_ctrl_impl::on_mouse_button_up(double, double) - { - m_move_what = move_nothing; - return false; - } - - - //------------------------------------------------------------------------ - bool scale_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) - { -/* - if(right || up) - { - m_value += 0.005; - if(m_value > 1.0) m_value = 1.0; - return true; - } - - if(left || down) - { - m_value -= 0.005; - if(m_value < 0.0) m_value = 0.0; - return true; - } -*/ - return false; - } - -} - diff --git a/src/libs/agg/src/ctrl/agg_slider_ctrl.cpp b/src/libs/agg/src/ctrl/agg_slider_ctrl.cpp deleted file mode 100644 index 75c2a0b1fa..0000000000 --- a/src/libs/agg/src/ctrl/agg_slider_ctrl.cpp +++ /dev/null @@ -1,349 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes slider_ctrl_impl, slider_ctrl -// -//---------------------------------------------------------------------------- - -#include -#include -#include "ctrl/agg_slider_ctrl.h" - -namespace agg -{ - - //------------------------------------------------------------------------ - slider_ctrl_impl::slider_ctrl_impl(double x1, double y1, - double x2, double y2, bool flip_y) : - ctrl(x1, y1, x2, y2, flip_y), - m_border_width(1.0), - m_border_extra((y2 - y1) / 2), - m_text_thickness(1.0), - m_pdx(0.0), - m_mouse_move(false), - m_value(0.5), - m_preview_value(0.5), - m_min(0.0), - m_max(1.0), - m_num_steps(0), - m_descending(false), - m_text_poly(m_text) - { - m_label[0] = 0; - calc_box(); - } - - - //------------------------------------------------------------------------ - void slider_ctrl_impl::calc_box() - { - m_xs1 = m_x1 + m_border_width; - m_ys1 = m_y1 + m_border_width; - m_xs2 = m_x2 - m_border_width; - m_ys2 = m_y2 - m_border_width; - } - - - //------------------------------------------------------------------------ - bool slider_ctrl_impl::normalize_value(bool preview_value_flag) - { - bool ret = true; - if(m_num_steps) - { - int step = int(m_preview_value * m_num_steps + 0.5); - ret = m_value != step / double(m_num_steps); - m_value = step / double(m_num_steps); - } - else - { - m_value = m_preview_value; - } - - if(preview_value_flag) - { - m_preview_value = m_value; - } - return ret; - } - - - //------------------------------------------------------------------------ - void slider_ctrl_impl::border_width(double t, double extra) - { - m_border_width = t; - m_border_extra = extra; - calc_box(); - } - - - //------------------------------------------------------------------------ - void slider_ctrl_impl::value(double value) - { - m_preview_value = (value - m_min) / (m_max - m_min); - if(m_preview_value > 1.0) m_preview_value = 1.0; - if(m_preview_value < 0.0) m_preview_value = 0.0; - normalize_value(true); - } - - //------------------------------------------------------------------------ - void slider_ctrl_impl::label(const char* fmt) - { - m_label[0] = 0; - if(fmt) - { - unsigned len = strlen(fmt); - if(len > 63) len = 63; - memcpy(m_label, fmt, len); - m_label[len] = 0; - } - } - - //------------------------------------------------------------------------ - void slider_ctrl_impl::rewind(unsigned idx) - { - m_idx = idx; - - switch(idx) - { - default: - - case 0: // Background - m_vertex = 0; - m_vx[0] = m_x1 - m_border_extra; - m_vy[0] = m_y1 - m_border_extra; - m_vx[1] = m_x2 + m_border_extra; - m_vy[1] = m_y1 - m_border_extra; - m_vx[2] = m_x2 + m_border_extra; - m_vy[2] = m_y2 + m_border_extra; - m_vx[3] = m_x1 - m_border_extra; - m_vy[3] = m_y2 + m_border_extra; - break; - - case 1: // Triangle - m_vertex = 0; - if(m_descending) - { - m_vx[0] = m_x1; - m_vy[0] = m_y1; - m_vx[1] = m_x2; - m_vy[1] = m_y1; - m_vx[2] = m_x1; - m_vy[2] = m_y2; - m_vx[3] = m_x1; - m_vy[3] = m_y1; - } - else - { - m_vx[0] = m_x1; - m_vy[0] = m_y1; - m_vx[1] = m_x2; - m_vy[1] = m_y1; - m_vx[2] = m_x2; - m_vy[2] = m_y2; - m_vx[3] = m_x1; - m_vy[3] = m_y1; - } - break; - - case 2: - m_text.text(m_label); - if(m_label[0]) - { - char buf[256]; - sprintf(buf, m_label, value()); - m_text.text(buf); - } - m_text.start_point(m_x1, m_y1); - m_text.size((m_y2 - m_y1) * 1.2, m_y2 - m_y1); - m_text_poly.width(m_text_thickness); - m_text_poly.line_join(round_join); - m_text_poly.line_cap(round_cap); - m_text_poly.rewind(0); - break; - - case 3: // pointer preview - m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_preview_value, - (m_ys1 + m_ys2) / 2.0, - m_y2 - m_y1, - m_y2 - m_y1, - 32); - break; - - - case 4: // pointer - normalize_value(false); - m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value, - (m_ys1 + m_ys2) / 2.0, - m_y2 - m_y1, - m_y2 - m_y1, - 32); - m_ellipse.rewind(0); - break; - - case 5: - m_storage.remove_all(); - if(m_num_steps) - { - unsigned i; - double d = (m_xs2 - m_xs1) / m_num_steps; - if(d > 0.004) d = 0.004; - for(i = 0; i < m_num_steps + 1; i++) - { - double x = m_xs1 + (m_xs2 - m_xs1) * i / m_num_steps; - m_storage.move_to(x, m_y1); - m_storage.line_to(x - d * (m_x2 - m_x1), m_y1 - m_border_extra); - m_storage.line_to(x + d * (m_x2 - m_x1), m_y1 - m_border_extra); - } - } - } - } - - - //------------------------------------------------------------------------ - unsigned slider_ctrl_impl::vertex(double* x, double* y) - { - unsigned cmd = path_cmd_line_to; - switch(m_idx) - { - case 0: - if(m_vertex == 0) cmd = path_cmd_move_to; - if(m_vertex >= 4) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 1: - if(m_vertex == 0) cmd = path_cmd_move_to; - if(m_vertex >= 4) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 2: - cmd = m_text_poly.vertex(x, y); - break; - - case 3: - case 4: - cmd = m_ellipse.vertex(x, y); - break; - - case 5: - cmd = m_storage.vertex(x, y); - break; - - default: - cmd = path_cmd_stop; - break; - } - - if(!is_stop(cmd)) - { - transform_xy(x, y); - } - - return cmd; - } - - - - //------------------------------------------------------------------------ - bool slider_ctrl_impl::in_rect(double x, double y) const - { - inverse_transform_xy(&x, &y); - return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; - } - - - //------------------------------------------------------------------------ - bool slider_ctrl_impl::on_mouse_button_down(double x, double y) - { - inverse_transform_xy(&x, &y); - - double xp = m_xs1 + (m_xs2 - m_xs1) * m_value; - double yp = (m_ys1 + m_ys2) / 2.0; - - if(calc_distance(x, y, xp, yp) <= m_y2 - m_y1) - { - m_pdx = xp - x; - m_mouse_move = true; - return true; - } - return false; - } - - - //------------------------------------------------------------------------ - bool slider_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) - { - inverse_transform_xy(&x, &y); - if(!button_flag) - { - on_mouse_button_up(x, y); - return false; - } - - if(m_mouse_move) - { - double xp = x + m_pdx; - m_preview_value = (xp - m_xs1) / (m_xs2 - m_xs1); - if(m_preview_value < 0.0) m_preview_value = 0.0; - if(m_preview_value > 1.0) m_preview_value = 1.0; - return true; - } - return false; - } - - - //------------------------------------------------------------------------ - bool slider_ctrl_impl::on_mouse_button_up(double, double) - { - m_mouse_move = false; - normalize_value(true); - return true; - } - - - //------------------------------------------------------------------------ - bool slider_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) - { - double d = 0.005; - if(m_num_steps) - { - d = 1.0 / m_num_steps; - } - - if(right || up) - { - m_preview_value += d; - if(m_preview_value > 1.0) m_preview_value = 1.0; - normalize_value(true); - return true; - } - - if(left || down) - { - m_preview_value -= d; - if(m_preview_value < 0.0) m_preview_value = 0.0; - normalize_value(true); - return true; - } - return false; - } - -} - diff --git a/src/libs/agg/src/ctrl/agg_spline_ctrl.cpp b/src/libs/agg/src/ctrl/agg_spline_ctrl.cpp deleted file mode 100644 index 5a12575cce..0000000000 --- a/src/libs/agg/src/ctrl/agg_spline_ctrl.cpp +++ /dev/null @@ -1,407 +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: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// classes spline_ctrl_impl, spline_ctrl -// -//---------------------------------------------------------------------------- - -#include "ctrl/agg_spline_ctrl.h" - - -namespace agg -{ - - //------------------------------------------------------------------------ - spline_ctrl_impl::spline_ctrl_impl(double x1, double y1, double x2, double y2, - unsigned num_pnt, bool flip_y) : - ctrl(x1, y1, x2, y2, flip_y), - m_num_pnt(num_pnt), - m_border_width(1.0), - m_border_extra(0.0), - m_curve_width(1.0), - m_point_size(3.0), - m_curve_poly(m_curve_pnt), - m_idx(0), - m_vertex(0), - m_active_pnt(-1), - m_move_pnt(-1), - m_pdx(0.0), - m_pdy(0.0) - { - if(m_num_pnt < 4) m_num_pnt = 4; - if(m_num_pnt > 32) m_num_pnt = 32; - - unsigned i; - for(i = 0; i < m_num_pnt; i++) - { - m_xp[i] = double(i) / double(m_num_pnt - 1); - m_yp[i] = 0.5; - } - calc_spline_box(); - update_spline(); - } - - - //------------------------------------------------------------------------ - void spline_ctrl_impl::border_width(double t, double extra) - { - m_border_width = t; - m_border_extra = extra; - calc_spline_box(); - } - - - //------------------------------------------------------------------------ - void spline_ctrl_impl::calc_spline_box() - { - m_xs1 = m_x1 + m_border_width; - m_ys1 = m_y1 + m_border_width; - m_xs2 = m_x2 - m_border_width; - m_ys2 = m_y2 - m_border_width; - } - - - //------------------------------------------------------------------------ - void spline_ctrl_impl::update_spline() - { - int i; - m_spline.init(m_num_pnt, m_xp, m_yp); - for(i = 0; i < 256; i++) - { - m_spline_values[i] = m_spline.get(double(i) / 255.0); - if(m_spline_values[i] < 0.0) m_spline_values[i] = 0.0; - if(m_spline_values[i] > 1.0) m_spline_values[i] = 1.0; - m_spline_values8[i] = (int8u)(m_spline_values[i] * 255.0); - } - } - - - //------------------------------------------------------------------------ - void spline_ctrl_impl::calc_curve() - { - int i; - m_curve_pnt.remove_all(); - m_curve_pnt.move_to(m_xs1, m_ys1 + (m_ys2 - m_ys1) * m_spline_values[0]); - for(i = 1; i < 256; i++) - { - m_curve_pnt.line_to(m_xs1 + (m_xs2 - m_xs1) * double(i) / 255.0, - m_ys1 + (m_ys2 - m_ys1) * m_spline_values[i]); - } - } - - - //------------------------------------------------------------------------ - double spline_ctrl_impl::calc_xp(unsigned idx) - { - return m_xs1 + (m_xs2 - m_xs1) * m_xp[idx]; - } - - - //------------------------------------------------------------------------ - double spline_ctrl_impl::calc_yp(unsigned idx) - { - return m_ys1 + (m_ys2 - m_ys1) * m_yp[idx]; - } - - - //------------------------------------------------------------------------ - void spline_ctrl_impl::set_xp(unsigned idx, double val) - { - if(val < 0.0) val = 0.0; - if(val > 1.0) val = 1.0; - - if(idx == 0) - { - val = 0.0; - } - else if(idx == m_num_pnt - 1) - { - val = 1.0; - } - else - { - if(val < m_xp[idx - 1] + 0.001) val = m_xp[idx - 1] + 0.001; - if(val > m_xp[idx + 1] - 0.001) val = m_xp[idx + 1] - 0.001; - } - m_xp[idx] = val; - } - - //------------------------------------------------------------------------ - void spline_ctrl_impl::set_yp(unsigned idx, double val) - { - if(val < 0.0) val = 0.0; - if(val > 1.0) val = 1.0; - m_yp[idx] = val; - } - - - //------------------------------------------------------------------------ - void spline_ctrl_impl::point(unsigned idx, double x, double y) - { - if(idx < m_num_pnt) - { - set_xp(idx, x); - set_yp(idx, y); - } - } - - - //------------------------------------------------------------------------ - void spline_ctrl_impl::value(unsigned idx, double y) - { - if(idx < m_num_pnt) - { - set_yp(idx, y); - } - } - - //------------------------------------------------------------------------ - double spline_ctrl_impl::value(double x) const - { - x = m_spline.get(x); - if(x < 0.0) x = 0.0; - if(x > 1.0) x = 1.0; - return x; - } - - - //------------------------------------------------------------------------ - void spline_ctrl_impl::rewind(unsigned idx) - { - unsigned i; - - m_idx = idx; - - switch(idx) - { - default: - - case 0: // Background - m_vertex = 0; - m_vx[0] = m_x1 - m_border_extra; - m_vy[0] = m_y1 - m_border_extra; - m_vx[1] = m_x2 + m_border_extra; - m_vy[1] = m_y1 - m_border_extra; - m_vx[2] = m_x2 + m_border_extra; - m_vy[2] = m_y2 + m_border_extra; - m_vx[3] = m_x1 - m_border_extra; - m_vy[3] = m_y2 + m_border_extra; - break; - - case 1: // Border - m_vertex = 0; - m_vx[0] = m_x1; - m_vy[0] = m_y1; - m_vx[1] = m_x2; - m_vy[1] = m_y1; - m_vx[2] = m_x2; - m_vy[2] = m_y2; - m_vx[3] = m_x1; - m_vy[3] = m_y2; - m_vx[4] = m_x1 + m_border_width; - m_vy[4] = m_y1 + m_border_width; - m_vx[5] = m_x1 + m_border_width; - m_vy[5] = m_y2 - m_border_width; - m_vx[6] = m_x2 - m_border_width; - m_vy[6] = m_y2 - m_border_width; - m_vx[7] = m_x2 - m_border_width; - m_vy[7] = m_y1 + m_border_width; - break; - - case 2: // Curve - calc_curve(); - m_curve_poly.width(m_curve_width); - m_curve_poly.rewind(0); - break; - - - case 3: // Inactive points - m_curve_pnt.remove_all(); - for(i = 0; i < m_num_pnt; i++) - { - if(int(i) != m_active_pnt) - { - m_ellipse.init(calc_xp(i), calc_yp(i), - m_point_size, m_point_size, 32); - m_curve_pnt.add_path(m_ellipse, 0, false); - } - } - m_curve_poly.rewind(0); - break; - - - case 4: // Active point - m_curve_pnt.remove_all(); - if(m_active_pnt >= 0) - { - m_ellipse.init(calc_xp(m_active_pnt), calc_yp(m_active_pnt), - m_point_size, m_point_size, 32); - - m_curve_pnt.add_path(m_ellipse); - } - m_curve_poly.rewind(0); - break; - - } - } - - - //------------------------------------------------------------------------ - unsigned spline_ctrl_impl::vertex(double* x, double* y) - { - unsigned cmd = path_cmd_line_to; - switch(m_idx) - { - case 0: - if(m_vertex == 0) cmd = path_cmd_move_to; - if(m_vertex >= 4) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 1: - if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; - if(m_vertex >= 8) cmd = path_cmd_stop; - *x = m_vx[m_vertex]; - *y = m_vy[m_vertex]; - m_vertex++; - break; - - case 2: - cmd = m_curve_poly.vertex(x, y); - break; - - case 3: - case 4: - cmd = m_curve_pnt.vertex(x, y); - break; - - default: - cmd = path_cmd_stop; - break; - } - - if(!is_stop(cmd)) - { - transform_xy(x, y); - } - - return cmd; - } - - - - //------------------------------------------------------------------------ - void spline_ctrl_impl::active_point(int i) - { - m_active_pnt = i; - } - - - //------------------------------------------------------------------------ - bool spline_ctrl_impl::in_rect(double x, double y) const - { - inverse_transform_xy(&x, &y); - return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; - } - - - //------------------------------------------------------------------------ - bool spline_ctrl_impl::on_mouse_button_down(double x, double y) - { - inverse_transform_xy(&x, &y); - unsigned i; - for(i = 0; i < m_num_pnt; i++) - { - double xp = calc_xp(i); - double yp = calc_yp(i); - if(calc_distance(x, y, xp, yp) <= m_point_size + 1) - { - m_pdx = xp - x; - m_pdy = yp - y; - m_active_pnt = m_move_pnt = int(i); - return true; - } - } - return false; - } - - - //------------------------------------------------------------------------ - bool spline_ctrl_impl::on_mouse_button_up(double, double) - { - if(m_move_pnt >= 0) - { - m_move_pnt = -1; - return true; - } - return false; - } - - - //------------------------------------------------------------------------ - bool spline_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) - { - inverse_transform_xy(&x, &y); - if(!button_flag) - { - return on_mouse_button_up(x, y); - } - - if(m_move_pnt >= 0) - { - double xp = x + m_pdx; - double yp = y + m_pdy; - - set_xp(m_move_pnt, (xp - m_xs1) / (m_xs2 - m_xs1)); - set_yp(m_move_pnt, (yp - m_ys1) / (m_ys2 - m_ys1)); - - update_spline(); - return true; - } - return false; - } - - - //------------------------------------------------------------------------ - bool spline_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) - { - double kx = 0.0; - double ky = 0.0; - bool ret = false; - if(m_active_pnt >= 0) - { - kx = m_xp[m_active_pnt]; - ky = m_yp[m_active_pnt]; - if(left) { kx -= 0.001; ret = true; } - if(right) { kx += 0.001; ret = true; } - if(down) { ky -= 0.001; ret = true; } - if(up) { ky += 0.001; ret = true; } - } - if(ret) - { - set_xp(m_active_pnt, kx); - set_yp(m_active_pnt, ky); - update_spline(); - } - return ret; - } - - - - -} - diff --git a/src/libs/agg/src/platform/BeOS/agg_platform_support.cpp b/src/libs/agg/src/platform/BeOS/agg_platform_support.cpp deleted file mode 100644 index 4db743b227..0000000000 --- a/src/libs/agg/src/platform/BeOS/agg_platform_support.cpp +++ /dev/null @@ -1,837 +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: superstippi@gmx.de -//---------------------------------------------------------------------------- -// -// class platform_support -// -//---------------------------------------------------------------------------- - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "platform/agg_platform_support.h" -#include "util/agg_color_conv_rgb8.h" - -class AGGView : public BView { - public: - AGGView(BRect frame, agg::platform_support* agg, agg::pix_format_e format, bool flipY) - : BView(frame, "AGG View", B_FOLLOW_ALL, - B_FRAME_EVENTS | B_WILL_DRAW), - fAGG(agg), - fFormat(format), - fFlipY(flipY), - fRedraw(true), - fPulse(NULL), - fLastPulse(0), - fEnableTicks(true) - { - SetViewColor(B_TRANSPARENT_32_BIT); - - frame.OffsetTo(0.0, 0.0); - fBitmap = new BBitmap(frame, 0, B_RGBA32); - if (fBitmap->IsValid()) { - memset(fBitmap->Bits(), 0, fBitmap->BitsLength()); - fAGG->rbuf_window().attach((uint8*)fBitmap->Bits(), - fBitmap->Bounds().IntegerWidth() + 1, - fBitmap->Bounds().IntegerHeight() + 1, - fFlipY ? -fBitmap->BytesPerRow() : fBitmap->BytesPerRow()); - } else { - delete fBitmap; - fBitmap = NULL; - } - } - - virtual ~AGGView() - { - delete fBitmap; - delete fPulse; - } - - virtual void AttachedToWindow() - { - BMessage message('tick'); - BMessenger target(this, Looper()); - delete fPulse; -// BScreen screen; -// TODO: calc screen retrace - fPulse = new BMessageRunner(target, &message, 40000); - - // make sure we call this once - fAGG->on_resize(Bounds().IntegerWidth() + 1, - Bounds().IntegerHeight() + 1); - } - virtual void DetachedFromWindow() - { - delete fPulse; - fPulse = NULL; - } - - virtual void MessageReceived(BMessage* message) - { - bigtime_t now = system_time(); - switch (message->what) { - case 'tick': - // drop messages that have piled up - if (/*now - fLastPulse > 30000*/fEnableTicks) { - fLastPulse = now; - if (!fAGG->wait_mode()) - fAGG->on_idle(); - Window()->PostMessage('entk', this); - fEnableTicks = false; - } else { -// fprintf(stderr, "dropping tick message (%lld)\n", now - fLastPulse); - } - break; - case 'entk': - fEnableTicks = true; - if (now - fLastPulse > 30000) { - fLastPulse = now; - if (!fAGG->wait_mode()) - fAGG->on_idle(); - } - break; - default: - BView::MessageReceived(message); - break; - } - } - - virtual void Draw(BRect updateRect) - { - if (fBitmap) { - if (fRedraw) { - fAGG->on_draw(); - fRedraw = false; - } - if (fFormat == agg::pix_format_bgra32) { - DrawBitmap(fBitmap, updateRect, updateRect); - } else { - BBitmap* bitmap = new BBitmap(fBitmap->Bounds(), 0, B_RGBA32); - - agg::rendering_buffer rbuf_src; - rbuf_src.attach((uint8*)fBitmap->Bits(), - fBitmap->Bounds().IntegerWidth() + 1, - fBitmap->Bounds().IntegerHeight() + 1, - fFlipY ? -fBitmap->BytesPerRow() : fBitmap->BytesPerRow()); - - agg::rendering_buffer rbuf_dst; - rbuf_dst.attach((uint8*)bitmap->Bits(), - bitmap->Bounds().IntegerWidth() + 1, - bitmap->Bounds().IntegerHeight() + 1, - fFlipY ? -bitmap->BytesPerRow() : bitmap->BytesPerRow()); - switch(fFormat) { - case agg::pix_format_rgb555: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_rgb555_to_bgra32()); break; - case agg::pix_format_rgb565: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_rgb565_to_bgra32()); break; - case agg::pix_format_rgb24: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_rgb24_to_bgra32()); break; - case agg::pix_format_bgr24: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_bgr24_to_bgra32()); break; - case agg::pix_format_rgba32: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_rgba32_to_bgra32()); break; - case agg::pix_format_argb32: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_argb32_to_bgra32()); break; - case agg::pix_format_abgr32: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_abgr32_to_bgra32()); break; - case agg::pix_format_bgra32: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_bgra32_to_bgra32()); break; - } - DrawBitmap(bitmap, updateRect, updateRect); - delete bitmap; - } - } else { - FillRect(updateRect); - } - } - - virtual void FrameResized(float width, float height) - { - BRect r(0.0, 0.0, width, height); - BBitmap* bitmap = new BBitmap(r, 0, B_RGBA32); - if (bitmap->IsValid()) { - delete fBitmap; - fBitmap = bitmap; - fAGG->rbuf_window().attach((uint8*)fBitmap->Bits(), - fBitmap->Bounds().IntegerWidth() + 1, - fBitmap->Bounds().IntegerHeight() + 1, - fFlipY ? -fBitmap->BytesPerRow() : fBitmap->BytesPerRow()); - - fAGG->trans_affine_resizing((int)width + 1, - (int)height + 1); - - // pass the event on to AGG - fAGG->on_resize((int)width + 1, - (int)height + 1); - - fRedraw = true; - Invalidate(); - } else - delete bitmap; - } - - virtual void KeyDown(const char* bytes, int32 numBytes) - { - if (bytes && numBytes > 0) { - fLastKeyDown = bytes[0]; - - bool left = false; - bool up = false; - bool right = false; - bool down = false; - - switch (fLastKeyDown) { - - case B_LEFT_ARROW: - left = true; - break; - - case B_UP_ARROW: - up = true; - break; - - case B_RIGHT_ARROW: - right = true; - break; - - case B_DOWN_ARROW: - down = true; - break; - } - -/* case key_f2: - fAGG->copy_window_to_img(agg::platform_support::max_images - 1); - fAGG->save_img(agg::platform_support::max_images - 1, "screenshot"); - break; - }*/ - - - if (fAGG->m_ctrls.on_arrow_keys(left, right, down, up)) { - fAGG->on_ctrl_change(); - fAGG->force_redraw(); - } else { - fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); - } -// fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); - - } - } - virtual void MouseDown(BPoint where) - { - BMessage* currentMessage = Window()->CurrentMessage(); - if (currentMessage) { - if (currentMessage->FindInt32("buttons", (int32*)&fMouseButtons) < B_OK) - fMouseButtons = B_PRIMARY_MOUSE_BUTTON; - } else - fMouseButtons = B_PRIMARY_MOUSE_BUTTON; - - fMouseX = (int)where.x; - fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; - - // pass the event on to AGG - if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { - // left mouse button -> see if to handle in controls - fAGG->m_ctrls.set_cur(fMouseX, fMouseY); - if (fAGG->m_ctrls.on_mouse_button_down(fMouseX, fMouseY)) { - fAGG->on_ctrl_change(); - fAGG->force_redraw(); - } else { - if (fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { - if (fAGG->m_ctrls.set_cur(fMouseX, fMouseY)) { - fAGG->on_ctrl_change(); - fAGG->force_redraw(); - } - } else { - fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); - } - } - } else if (fMouseButtons & B_SECONDARY_MOUSE_BUTTON) { - // right mouse button -> simple - fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); - } - SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); - } - virtual void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMesage) - { - // workarround missed mouse up events - // (if we react too slowly, app_server might have dropped events) - BMessage* currentMessage = Window()->CurrentMessage(); - int32 buttons = 0; - if (currentMessage->FindInt32("buttons", &buttons) < B_OK) { - buttons = 0; - } - if (!buttons) - MouseUp(where); - - fMouseX = (int)where.x; - fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; - - // pass the event on to AGG - if (fAGG->m_ctrls.on_mouse_move(fMouseX, fMouseY, - (GetKeyFlags() & agg::mouse_left) != 0)) { - fAGG->on_ctrl_change(); - fAGG->force_redraw(); - } else { - if (!fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { - fAGG->on_mouse_move(fMouseX, fMouseY, GetKeyFlags()); - } - } - } - - virtual void MouseUp(BPoint where) - { - fMouseX = (int)where.x; - fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; - - // pass the event on to AGG - if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { - fMouseButtons = 0; - - if (fAGG->m_ctrls.on_mouse_button_up(fMouseX, fMouseY)) { - fAGG->on_ctrl_change(); - fAGG->force_redraw(); - } - fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); - } else if (fMouseButtons == B_SECONDARY_MOUSE_BUTTON) { - fMouseButtons = 0; - - fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); - } - } - - BBitmap* Bitmap() const - { - return fBitmap; - } - - uint8 LastKeyDown() const - { - return fLastKeyDown; - } - uint32 MouseButtons() - { - uint32 buttons = 0; - if (LockLooper()) { - buttons = fMouseButtons; - UnlockLooper(); - } - return buttons; - } - - void Update() - { - // trigger display update - if (LockLooper()) { - Invalidate(); - UnlockLooper(); - } - } - - void ForceRedraw() - { - // force a redraw (fRedraw = true;) - // and trigger display update - if (LockLooper()) { - fRedraw = true; - Invalidate(); - UnlockLooper(); - } - } - - unsigned GetKeyFlags() - { - uint32 buttons = fMouseButtons; - uint32 mods = modifiers(); - unsigned flags = 0; - if (buttons & B_PRIMARY_MOUSE_BUTTON) flags |= agg::mouse_left; - if (buttons & B_SECONDARY_MOUSE_BUTTON) flags |= agg::mouse_right; - if (mods & B_SHIFT_KEY) flags |= agg::kbd_shift; - if (mods & B_COMMAND_KEY) flags |= agg::kbd_ctrl; - return flags; - } - - private: - BBitmap* fBitmap; - uint8 fLastKeyDown; - agg::platform_support* fAGG; - agg::pix_format_e fFormat; - - uint32 fMouseButtons; - int32 fMouseX; - int32 fMouseY; - bool fFlipY; - bool fRedraw; - BMessageRunner* fPulse; - bigtime_t fLastPulse; - bool fEnableTicks; -}; - -class AGGWindow : public BWindow { - public: - AGGWindow() - : BWindow(BRect(-50.0, -50.0, -10.0, -10.0), - "AGG Application", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS) - { - } - - virtual bool QuitRequested() - { - be_app->PostMessage(B_QUIT_REQUESTED); - return true; - } - - bool Init(BRect frame, agg::platform_support* agg, agg::pix_format_e format, - bool flipY, uint32 flags) - { - MoveTo(frame.LeftTop()); - ResizeTo(frame.Width(), frame.Height()); - - SetFlags(flags); - - frame.OffsetTo(0.0, 0.0); - fView = new AGGView(frame, agg, format, flipY); - AddChild(fView); - - return fView->Bitmap() != NULL; - } - - - AGGView* View() const - { - return fView; - } - private: - AGGView* fView; -}; - -class AGGApplication : public BApplication { - public: - AGGApplication() - : BApplication("application/x-vnd.AGG-AGG") - { - fWindow = new AGGWindow(); - } - - virtual void ReadyToRun() - { - if (fWindow) { - fWindow->Show(); - } - } - - virtual bool Init(agg::platform_support* agg, int width, int height, - agg::pix_format_e format, bool flipY, uint32 flags) - { - // ignore flip_y for now - BRect r(50.0, 50.0, - 50.0 + width - 1.0, - 50.0 + height - 1.0); - uint32 windowFlags = B_ASYNCHRONOUS_CONTROLS; - if (!(flags & agg::window_resize)) - windowFlags |= B_NOT_RESIZABLE; - - return fWindow->Init(r, agg, format, flipY, windowFlags);; - } - - - AGGWindow* Window() const - { - return fWindow; - } - - private: - AGGWindow* fWindow; -}; - -namespace agg -{ - -class platform_specific { - public: - platform_specific(agg::platform_support* agg, - agg::pix_format_e format, bool flip_y) - : fAGG(agg), - fApp(NULL), - fFormat(format), - fFlipY(flip_y), - fTimerStart(system_time()) - { - memset(fImages, 0, sizeof(fImages)); - fApp = new AGGApplication(); - fAppPath[0] = 0; - // figure out where we're running from - app_info info; - status_t ret = be_roster->GetRunningAppInfo(be_app->Team(), &info); - if (ret >= B_OK) { - BPath path(&info.ref); - ret = path.InitCheck(); - if (ret >= B_OK) { - ret = path.GetParent(&path); - if (ret >= B_OK) { - sprintf(fAppPath, "%s", path.Path()); - } else { - fprintf(stderr, "getting app parent folder failed: %s\n", strerror(ret)); - } - } else { - fprintf(stderr, "making app path failed: %s\n", strerror(ret)); - } - } else { - fprintf(stderr, "GetRunningAppInfo() failed: %s\n", strerror(ret)); - } - } - ~platform_specific() - { - for (int32 i = 0; i < agg::platform_support::max_images; i++) - delete fImages[i]; - delete fApp; - } - - bool Init(int width, int height, unsigned flags) - { - return fApp->Init(fAGG, width, height, fFormat, fFlipY, flags); - } - - int Run() - { - status_t ret = B_NO_INIT; - if (fApp) { - fApp->Run(); - ret = B_OK; - } - return ret; - } - - void SetTitle(const char* title) - { - if (fApp && fApp->Window() && fApp->Window()->Lock()) { - fApp->Window()->SetTitle(title); - fApp->Window()->Unlock(); - } - } - void StartTimer() - { - fTimerStart = system_time(); - } - double ElapsedTime() const - { - return (system_time() - fTimerStart) / 1000.0; - } - - void ForceRedraw() - { - fApp->Window()->View()->ForceRedraw(); - } - void UpdateWindow() - { - fApp->Window()->View()->Update(); - } - - - agg::platform_support* fAGG; - AGGApplication* fApp; - agg::pix_format_e fFormat; - bool fFlipY; - bigtime_t fTimerStart; - BBitmap* fImages[agg::platform_support::max_images]; - - char fAppPath[B_PATH_NAME_LENGTH]; - char fFilePath[B_PATH_NAME_LENGTH]; -}; - - - //------------------------------------------------------------------------ - platform_support::platform_support(pix_format_e format, bool flip_y) : - m_specific(new platform_specific(this, format, flip_y)), - m_format(format), - m_bpp(32/*m_specific->m_bpp*/), - m_window_flags(0), - m_wait_mode(true), - m_flip_y(flip_y), - m_initial_width(10), - m_initial_height(10) - { - strcpy(m_caption, "Anti-Grain Geometry Application"); - } - - - //------------------------------------------------------------------------ - platform_support::~platform_support() - { - delete m_specific; - } - - //------------------------------------------------------------------------ - void platform_support::caption(const char* cap) - { - strcpy(m_caption, cap); - m_specific->SetTitle(cap); - } - - //------------------------------------------------------------------------ - void platform_support::start_timer() - { - m_specific->StartTimer(); - } - - //------------------------------------------------------------------------ - double platform_support::elapsed_time() const - { - return m_specific->ElapsedTime(); - } - - //------------------------------------------------------------------------ - void* platform_support::raw_display_handler() - { - return NULL;//m_specific->m_current_dc; - } - - //------------------------------------------------------------------------ - void platform_support::message(const char* msg) - { - BAlert* alert = new BAlert("AGG Message", msg, "Ok"); - alert->Go(/*NULL*/); - } - - //------------------------------------------------------------------------ - bool platform_support::init(unsigned width, unsigned height, unsigned flags) - { - bool success = m_specific->Init(width, height, flags); - - m_window_flags = flags; - -// m_specific->create_pmap(width, height, &m_rbuf_window); - m_initial_width = width; - m_initial_height = height; - on_init(); -// m_specific->m_redraw_flag = true; - return true; - } - - - - //------------------------------------------------------------------------ - int platform_support::run() - { - return m_specific->Run(); - } - - - //------------------------------------------------------------------------ - const char* platform_support::img_ext() const { return ""; } - - const char* platform_support::full_file_name(const char* file_name) - { - sprintf(m_specific->fFilePath, "%s/%s", m_specific->fAppPath, file_name); - return m_specific->fFilePath; - } - - - //------------------------------------------------------------------------ - bool platform_support::load_img(unsigned idx, const char* file) - { - if (idx < max_images) - { - BBitmap* transBitmap = BTranslationUtils::GetBitmap(full_file_name(file)); - if (transBitmap && transBitmap->IsValid()) { - if(transBitmap->ColorSpace() != B_RGB32 && transBitmap->ColorSpace() != B_RGBA32) { - // ups we got a smart ass Translator making our live harder - delete transBitmap; - return false; - } - - color_space format = B_RGB24; - - switch (m_format) { - case pix_format_gray8: - format = B_GRAY8; - break; - case pix_format_rgb555: - format = B_RGB15; - break; - case pix_format_rgb565: - format = B_RGB16; - break; - case pix_format_rgb24: - format = B_RGB24_BIG; - break; - case pix_format_bgr24: - format = B_RGB24; - break; - case pix_format_abgr32: - case pix_format_argb32: - case pix_format_bgra32: - format = B_RGB32; - break; - case pix_format_rgba32: - format = B_RGB32_BIG; - break; - } - BBitmap* bitmap = new BBitmap(transBitmap->Bounds(), 0, format); - if (!bitmap || !bitmap->IsValid()) { - fprintf(stderr, "failed to allocate temporary bitmap!\n"); - delete transBitmap; - delete bitmap; - return false; - } - - delete m_specific->fImages[idx]; - - rendering_buffer rbuf_tmp; - rbuf_tmp.attach((uint8*)transBitmap->Bits(), - transBitmap->Bounds().IntegerWidth() + 1, - transBitmap->Bounds().IntegerHeight() + 1, - m_flip_y ? -transBitmap->BytesPerRow() : transBitmap->BytesPerRow()); - - m_specific->fImages[idx] = bitmap; - - m_rbuf_img[idx].attach((uint8*)bitmap->Bits(), - bitmap->Bounds().IntegerWidth() + 1, - bitmap->Bounds().IntegerHeight() + 1, - m_flip_y ? -bitmap->BytesPerRow() : bitmap->BytesPerRow()); - - rendering_buffer* dst = &m_rbuf_img[idx]; - - switch(m_format) - { - case pix_format_gray8: - return false; -// color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break; - break; - - case pix_format_rgb555: - color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break; - break; - - case pix_format_rgb565: - color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break; - break; - - case pix_format_rgb24: - color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break; - break; - - case pix_format_bgr24: - color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break; - break; - - case pix_format_abgr32: - color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break; - break; - - case pix_format_argb32: - color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break; - break; - - case pix_format_bgra32: - color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break; - break; - - case pix_format_rgba32: - color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break; - break; - } - delete transBitmap; - - return true; - - } else { - fprintf(stderr, "failed to load bitmap: '%s'\n",full_file_name(file)); - } - } - return false; - } - - - - //------------------------------------------------------------------------ - bool platform_support::save_img(unsigned idx, const char* file) - { - // TODO: implement using BTranslatorRoster and friends - return false; - } - - - - //------------------------------------------------------------------------ - bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) - { - if(idx < max_images) - { - if(width == 0) width = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerWidth() + 1; - if(height == 0) height = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerHeight() + 1; - BBitmap* bitmap = new BBitmap(BRect(0.0, 0.0, width - 1, height - 1), 0, B_RGBA32);; - if (bitmap && bitmap->IsValid()) { - delete m_specific->fImages[idx]; - m_specific->fImages[idx] = bitmap; - m_rbuf_img[idx].attach((uint8*)bitmap->Bits(), - width, height, - m_flip_y ? -bitmap->BytesPerRow() : bitmap->BytesPerRow()); - return true; - } else { - delete bitmap; - } - } - return false; - } - - - //------------------------------------------------------------------------ - void platform_support::force_redraw() - { - m_specific->ForceRedraw(); - } - - - - //------------------------------------------------------------------------ - void platform_support::update_window() - { - m_specific->UpdateWindow(); - } - - - //------------------------------------------------------------------------ - void platform_support::on_init() {} - void platform_support::on_resize(int sx, int sy) {} - void platform_support::on_idle() {} - void platform_support::on_mouse_move(int x, int y, unsigned flags) {} - void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} - void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} - void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} - void platform_support::on_ctrl_change() {} - void platform_support::on_draw() {} - void platform_support::on_post_draw(void* raw_handler) {} -} - - - - - - -//---------------------------------------------------------------------------- -int agg_main(int argc, char* argv[]); - - - -int -main(int argc, char* argv[]) -{ - return agg_main(argc, argv); -} - - - - diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index d1eafe5105..358abf462c 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -21,9 +21,12 @@ #include #include #include +#include #include +#include #include -#include +#include +#include #include #include "drawing_support.h" @@ -361,7 +364,7 @@ Painter::StraightLine(BPoint a, BPoint b, const rgb_color& c) const if (fBuffer && fValidClipping) { if (a.x == b.x) { // vertical - uint8* dst = fBuffer->row(0); + uint8* dst = fBuffer->row_ptr(0); uint32 bpr = fBuffer->stride(); int32 x = (int32)a.x; dst += x * 4; @@ -392,7 +395,7 @@ Painter::StraightLine(BPoint a, BPoint b, const rgb_color& c) const } else if (a.y == b.y) { // horizontal int32 y = (int32)a.y; - uint8* dst = fBuffer->row(y); + uint8* dst = fBuffer->row_ptr(y); int32 x1 = (int32)min_c(a.x, b.x); int32 x2 = (int32)max_c(a.x, b.x); pixel32 color; @@ -680,7 +683,7 @@ void Painter::FillRect(const BRect& r, const rgb_color& c) const { if (fBuffer && fValidClipping) { - uint8* dst = fBuffer->row(0); + uint8* dst = fBuffer->row_ptr(0); uint32 bpr = fBuffer->stride(); int32 left = (int32)r.left; int32 top = (int32)r.top; @@ -723,7 +726,7 @@ Painter::FillRectNoClipping(const BRect& r, const rgb_color& c) const int32 right = (int32)r.right; int32 bottom = (int32)r.bottom; - uint8* dst = fBuffer->row(y); + uint8* dst = fBuffer->row_ptr(y); uint32 bpr = fBuffer->stride(); // get a 32 bit pixel ready with the color @@ -1313,7 +1316,7 @@ copy_bitmap_row_bgr32_alpha(uint8* dst, const uint8* src, int32 numPixels, // _DrawBitmap void -Painter::_DrawBitmap(const agg::rendering_buffer& srcBuffer, color_space format, +Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format, BRect actualBitmapRect, BRect bitmapRect, BRect viewRect) const { if (!fBuffer || !fValidClipping @@ -1431,15 +1434,15 @@ Painter::_DrawBitmap(const agg::rendering_buffer& srcBuffer, color_space format, template void Painter::_DrawBitmapNoScale32(F copyRowFunction, uint32 bytesPerSourcePixel, - const agg::rendering_buffer& srcBuffer, + agg::rendering_buffer& srcBuffer, int32 xOffset, int32 yOffset, BRect viewRect) const { // NOTE: this would crash if viewRect was large enough to read outside the // bitmap, so make sure this is not the case before calling this function! - uint8* dst = fBuffer->row(0); + uint8* dst = fBuffer->row_ptr(0); uint32 dstBPR = fBuffer->stride(); - const uint8* src = srcBuffer.row(0); + const uint8* src = srcBuffer.row_ptr(0); uint32 srcBPR = srcBuffer.stride(); int32 left = (int32)viewRect.left; @@ -1474,33 +1477,43 @@ Painter::_DrawBitmapNoScale32(F copyRowFunction, uint32 bytesPerSourcePixel, // _DrawBitmapGeneric32 void -Painter::_DrawBitmapGeneric32(const agg::rendering_buffer& srcBuffer, +Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer, double xOffset, double yOffset, double xScale, double yScale, BRect viewRect) const { - typedef agg::span_allocator span_alloc_type; - // AGG pipeline - typedef agg::span_interpolator_linear<> interpolator_type; - typedef agg::span_image_filter_rgba32_nn scaled_span_gen_type; - typedef agg::renderer_scanline_aa scaled_image_renderer_type; + // pixel format attached to bitmap + typedef agg::pixfmt_bgra32 pixfmt_image; + pixfmt_image pixf_img(srcBuffer); agg::trans_affine srcMatrix; +// NOTE: R5 seems to ignore this offset when drawing bitmaps // srcMatrix *= agg::trans_affine_translation(-actualBitmapRect.left, -actualBitmapRect.top); agg::trans_affine imgMatrix; imgMatrix *= agg::trans_affine_scaling(xScale, yScale); imgMatrix *= agg::trans_affine_translation(xOffset, yOffset); imgMatrix.invert(); - - span_alloc_type sa; + + // image interpolator + typedef agg::span_interpolator_linear<> interpolator_type; interpolator_type interpolator(imgMatrix); - agg::rasterizer_scanline_aa<> pf; - agg::scanline_u8 sl; + // scanline allocator + agg::span_allocator spanAllocator; + + // image accessor attached to pixel format of bitmap + typedef agg::image_accessor_clip source_type; + source_type source(pixf_img, agg::rgba8(0, 0, 0, 0)); + + // image filter (nearest neighbor) + typedef agg::span_image_filter_rgba_nn span_gen_type; + span_gen_type spanGenerator(source, interpolator); + + // clip to the current clipping region's frame viewRect = viewRect & fClippingRegion->Frame(); @@ -1508,7 +1521,7 @@ Painter::_DrawBitmapGeneric32(const agg::rendering_buffer& srcBuffer, viewRect.right++; viewRect.bottom++; - // path encloses image + // path enclosing the bitmap agg::path_storage path; path.move_to(viewRect.left, viewRect.top); path.line_to(viewRect.right, viewRect.top); @@ -1516,14 +1529,15 @@ Painter::_DrawBitmapGeneric32(const agg::rendering_buffer& srcBuffer, path.line_to(viewRect.left, viewRect.bottom); path.close_polygon(); - agg::conv_transform tr(path, srcMatrix); + agg::conv_transform transformedPath(path, srcMatrix); + fRasterizer->add_path(transformedPath); - pf.add_path(tr); - - scaled_span_gen_type sg(sa, srcBuffer, agg::rgba(0, 0, 0, 0), interpolator); - scaled_image_renderer_type ri(*fBaseRenderer, sg); - - agg::render_scanlines(pf, sl, ri); + // render the path with the bitmap as scanline fill + agg::render_scanlines_aa(*fRasterizer, + *fUnpackedScanline, + *fBaseRenderer, + spanAllocator, + spanGenerator); } // _InvertRect32 @@ -1533,7 +1547,7 @@ Painter::_InvertRect32(BRect r) const if (fBuffer) { int32 width = r.IntegerWidth() + 1; for (int32 y = (int32)r.top; y <= (int32)r.bottom; y++) { - uint8* dst = fBuffer->row(y); + uint8* dst = fBuffer->row_ptr(y); dst += (int32)r.left * 4; for (int32 i = 0; i < width; i++) { dst[0] = 255 - dst[0]; @@ -1550,7 +1564,7 @@ void Painter::_BlendRect32(const BRect& r, const rgb_color& c) const { if (fBuffer && fValidClipping) { - uint8* dst = fBuffer->row(0); + uint8* dst = fBuffer->row_ptr(0); uint32 bpr = fBuffer->stride(); int32 left = (int32)r.left; diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index d1876bfcd5..a51ad0523d 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -213,7 +213,7 @@ class Painter { BPoint pt3, bool fill) const; - void _DrawBitmap( const agg::rendering_buffer& srcBuffer, + void _DrawBitmap( agg::rendering_buffer& srcBuffer, color_space format, BRect actualBitmapRect, BRect bitmapRect, @@ -222,11 +222,11 @@ class Painter { void _DrawBitmapNoScale32( F copyRowFunction, uint32 bytesPerSourcePixel, - const agg::rendering_buffer& srcBuffer, + agg::rendering_buffer& srcBuffer, int32 xOffset, int32 yOffset, BRect viewRect) const; void _DrawBitmapGeneric32( - const agg::rendering_buffer& srcBuffer, + agg::rendering_buffer& srcBuffer, double xOffset, double yOffset, double xScale, double yScale, BRect viewRect) const; diff --git a/src/servers/app/drawing/Painter/agg_renderer_region.h b/src/servers/app/drawing/Painter/agg_renderer_region.h index 70036208f3..6cc8f1567f 100644 --- a/src/servers/app/drawing/Painter/agg_renderer_region.h +++ b/src/servers/app/drawing/Painter/agg_renderer_region.h @@ -1,6 +1,6 @@ /* - * Copyright 2005, Stephan Aßmus . All rights reserved. - * Distributed under the terms of the MIT License. + * Copyright 2005-2006, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. * * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com) * @@ -48,18 +48,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() @@ -102,7 +102,7 @@ namespace agg if (m_region) { clipping_rect r = m_region->FrameInt(); if (r.left <= r.right && r.top <= r.bottom) { - // clip rect to frame buffer bounds + // clip rect_i to frame buffer bounds r.left = max_c(0, r.left); r.top = max_c(0, r.top); r.right = min_c((int)width() - 1, r.right); @@ -309,7 +309,7 @@ namespace agg //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, - const rect* rc=0, + const rect_i* rc=0, int x_to=0, int y_to=0) { @@ -329,7 +329,7 @@ namespace agg base_ren_type m_ren; BRegion* m_region; unsigned m_curr_cb; - rect m_bounds; + rect_i m_bounds; }; diff --git a/src/servers/app/drawing/Painter/defines.h b/src/servers/app/drawing/Painter/defines.h index bdac7c8e2a..03808b023e 100644 --- a/src/servers/app/drawing/Painter/defines.h +++ b/src/servers/app/drawing/Painter/defines.h @@ -1,5 +1,5 @@ /* - * Copyright 2005, Stephan Aßmus . All rights reserved. + * Copyright 2005-2006, Stephan Aßmus . All rights reserved. * Distributed under the terms of the MIT License. * * global definitions for the Painter frame work, mainly types for the diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAdd.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAdd.h index aa0e4b412c..23ba2a9985 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAdd.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAdd.h @@ -40,7 +40,7 @@ void blend_pixel_add(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); if (cover == 255) { ASSIGN_ADD(p, color.red, color.green, color.blue); @@ -55,7 +55,7 @@ blend_hline_add(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (cover == 255) { do { rgb_color color = pattern->R5ColorAt(x, y); @@ -83,7 +83,7 @@ blend_solid_hspan_add(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -107,7 +107,7 @@ blend_solid_vspan_add(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -131,7 +131,7 @@ blend_color_hspan_add(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCC.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCC.h index 23f5889e59..bbe0755045 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCC.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCC.h @@ -31,7 +31,7 @@ void blend_pixel_alpha_cc(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = pattern->HighColor().GetColor32().alpha * cover; if (alpha == 255 * 255) { @@ -67,7 +67,7 @@ blend_hline_alpha_cc(int x, int y, unsigned len, p8[2] = color.red; p8[3] = 255; // row offset as 32 bit pointer - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { if (pattern->IsHighColor(x, y)) *p32 = vh; @@ -77,7 +77,7 @@ blend_hline_alpha_cc(int x, int y, unsigned len, x++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); BLEND_ALPHA_CC(p, color.red, color.green, color.blue, alpha); @@ -93,7 +93,7 @@ blend_solid_hspan_alpha_cc(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint8 hAlpha = pattern->HighColor().GetColor32().alpha; do { rgb_color color = pattern->R5ColorAt(x, y); @@ -117,7 +117,7 @@ blend_solid_vspan_alpha_cc(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint8 hAlpha = pattern->HighColor().GetColor32().alpha; do { rgb_color color = pattern->R5ColorAt(x, y); @@ -143,7 +143,7 @@ blend_color_hspan_alpha_cc(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint8 hAlpha = pattern->HighColor().GetColor32().alpha; if (covers) { // non-solid opacity diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCO.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCO.h index a2e1a33757..5e4af1518c 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCO.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCO.h @@ -31,7 +31,7 @@ void blend_pixel_alpha_co(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = pattern->HighColor().GetColor32().alpha * cover; if (alpha == 255 * 255) { @@ -67,7 +67,7 @@ blend_hline_alpha_co(int x, int y, unsigned len, p8[2] = color.red; p8[3] = 255; // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { if (pattern->IsHighColor(x, y)) *p32 = vh; @@ -77,7 +77,7 @@ blend_hline_alpha_co(int x, int y, unsigned len, x++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha); @@ -93,7 +93,7 @@ blend_solid_hspan_alpha_co(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint8 hAlpha = pattern->HighColor().GetColor32().alpha; do { rgb_color color = pattern->R5ColorAt(x, y); @@ -119,7 +119,7 @@ blend_solid_vspan_alpha_co(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint8 hAlpha = pattern->HighColor().GetColor32().alpha; do { rgb_color color = pattern->R5ColorAt(x, y); @@ -145,7 +145,7 @@ blend_color_hspan_alpha_co(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint8 hAlpha = pattern->HighColor().GetColor32().alpha; if (covers) { // non-solid opacity diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolid.h index 94cfb78ce3..1498a7bd0e 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolid.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolid.h @@ -16,7 +16,7 @@ void blend_pixel_alpha_co_solid(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint16 alpha = pattern->HighColor().GetColor32().alpha * cover; if (alpha == 255 * 255) { ASSIGN_ALPHA_CO(p, c.r, c.g, c.b); @@ -41,14 +41,14 @@ blend_hline_alpha_co_solid(int x, int y, unsigned len, p8[2] = c.r; p8[3] = 255; // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { *p32 = v; p32++; x++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (len < 4) { do { BLEND_ALPHA_CO(p, c.r, c.g, c.b, alpha); @@ -68,7 +68,7 @@ blend_solid_hspan_alpha_co_solid(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint8 hAlpha = pattern->HighColor().GetColor32().alpha; do { uint16 alpha = hAlpha * *covers; @@ -93,7 +93,7 @@ blend_solid_vspan_alpha_co_solid(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint8 hAlpha = pattern->HighColor().GetColor32().alpha; do { uint16 alpha = hAlpha * *covers; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h index 2c64894782..4f07fe03e1 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h @@ -31,7 +31,7 @@ void blend_pixel_alpha_pc(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = color.alpha * cover; if (alpha == 255*255) { @@ -47,7 +47,7 @@ blend_hline_alpha_pc(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = color.alpha * cover; @@ -69,7 +69,7 @@ blend_solid_hspan_alpha_pc(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = color.alpha * *covers; @@ -92,7 +92,7 @@ blend_solid_vspan_alpha_pc(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = color.alpha * *covers; @@ -117,7 +117,7 @@ blend_color_hspan_alpha_pc(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h index 9fd0b46c6d..602f45e0ed 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h @@ -31,7 +31,7 @@ void blend_pixel_alpha_po(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = color.alpha * cover; if (alpha == 255 * 255) { @@ -47,7 +47,7 @@ blend_hline_alpha_po(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = color.alpha * cover; @@ -69,7 +69,7 @@ blend_solid_hspan_alpha_po(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = color.alpha * *covers; @@ -94,7 +94,7 @@ blend_solid_vspan_alpha_po(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); uint16 alpha = color.alpha * *covers; @@ -119,7 +119,7 @@ blend_color_hspan_alpha_po(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolid.h index 8f269dd781..53ea222f5b 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolid.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolid.h @@ -16,7 +16,7 @@ void blend_pixel_alpha_po_solid(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); uint16 alpha = c.a * cover; if (alpha == 255 * 255) { ASSIGN_ALPHA_PO(p, c.r, c.g, c.b); @@ -41,14 +41,14 @@ blend_hline_alpha_po_solid(int x, int y, unsigned len, p8[2] = c.r; p8[3] = 255; // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { *p32 = v; p32++; x++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (len < 4) { do { BLEND_ALPHA_CO(p, c.r, c.g, c.b, alpha); @@ -68,7 +68,7 @@ blend_solid_hspan_alpha_po_solid(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { uint16 alpha = c.a * *covers; if (alpha) { @@ -92,7 +92,7 @@ blend_solid_vspan_alpha_po_solid(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { uint16 alpha = c.a * *covers; if (alpha) { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlend.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlend.h index 55000b3268..a438c3822c 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlend.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlend.h @@ -38,7 +38,7 @@ void blend_pixel_blend(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); if (cover == 255) { ASSIGN_BLEND(p, color.red, color.green, color.blue); @@ -53,7 +53,7 @@ blend_hline_blend(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (cover == 255) { do { rgb_color color = pattern->R5ColorAt(x, y); @@ -81,7 +81,7 @@ blend_solid_hspan_blend(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -105,7 +105,7 @@ blend_solid_vspan_blend(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -129,7 +129,7 @@ blend_color_hspan_blend(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopy.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopy.h index 6eed677903..314a3f4675 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopy.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopy.h @@ -32,7 +32,7 @@ void blend_pixel_copy(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); if (cover == 255) { ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha); @@ -68,7 +68,7 @@ blend_hline_copy(int x, int y, unsigned len, p8[2] = (uint8)color.red; p8[3] = 255; // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { if (pattern->IsHighColor(x, y)) *p32 = vh; @@ -78,7 +78,7 @@ blend_hline_copy(int x, int y, unsigned len, x++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color l = pattern->LowColor().GetColor32(); do { rgb_color color = pattern->R5ColorAt(x, y); @@ -96,7 +96,7 @@ blend_solid_hspan_copy(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color l = pattern->LowColor().GetColor32(); do { rgb_color color = pattern->R5ColorAt(x, y); @@ -122,7 +122,7 @@ blend_solid_vspan_copy(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color l = pattern->LowColor().GetColor32(); do { rgb_color color = pattern->R5ColorAt(x, y); @@ -147,7 +147,7 @@ blend_color_hspan_copy(int x, int y, unsigned len, const color_type* colors, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color l = pattern->LowColor().GetColor32(); if (covers) { // non-solid opacity diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h index db69afd3e8..a473575c8a 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h @@ -16,7 +16,7 @@ void blend_pixel_copy_solid(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (cover == 255) { ASSIGN_OVER(p, c.r, c.g, c.b); } else { @@ -37,14 +37,14 @@ blend_hline_copy_solid(int x, int y, unsigned len, p8[1] = (uint8)c.g; p8[2] = (uint8)c.r; p8[3] = 255; - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { *p32 = v; p32++; x++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { BLEND_OVER(p, c.r, c.g, c.b, cover); x++; @@ -60,7 +60,7 @@ blend_solid_hspan_copy_solid(int x, int y, unsigned len, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { if (*covers) { if (*covers == 255) { @@ -84,7 +84,7 @@ blend_solid_vspan_copy_solid(int x, int y, unsigned len, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { if (*covers) { if (*covers == 255) { @@ -108,7 +108,7 @@ blend_color_hspan_copy_solid(int x, int y, unsigned len, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyText.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyText.h index 11dcfc5cf1..f67cf768f7 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyText.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyText.h @@ -16,7 +16,7 @@ void blend_pixel_copy_text(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (cover == 255) { ASSIGN_COPY(p, c.r, c.g, c.b, c.a); } else { @@ -41,13 +41,13 @@ blend_hline_copy_text(int x, int y, unsigned len, p8[2] = (uint8)c.r; p8[3] = 255; // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { *p32 = v; p32++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color l = pattern->LowColor().GetColor32(); do { BLEND_COPY(p, c.r, c.g, c.b, cover, @@ -64,7 +64,7 @@ blend_solid_hspan_copy_text(int x, int y, unsigned len, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color l = pattern->LowColor().GetColor32(); do { if (*covers) { @@ -89,7 +89,7 @@ blend_solid_vspan_copy_text(int x, int y, unsigned len, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color l = pattern->LowColor().GetColor32(); do { if (*covers) { @@ -114,7 +114,7 @@ blend_color_hspan_copy_text(int x, int y, unsigned len, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color l = pattern->LowColor().GetColor32(); if (covers) { // non-solid opacity diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h index 3ede73a681..52003659dc 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h @@ -32,7 +32,7 @@ blend_pixel_erase(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { if (pattern->IsHighColor(x, y)) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->LowColor().GetColor32(); if (cover == 255) { ASSIGN_ERASE(p, color.red, color.green, color.blue); @@ -56,7 +56,7 @@ blend_hline_erase(int x, int y, unsigned len, p8[1] = (uint8)color.green; p8[2] = (uint8)color.red; p8[3] = 255; - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { if (pattern->IsHighColor(x, y)) *p32 = v; @@ -64,7 +64,7 @@ blend_hline_erase(int x, int y, unsigned len, x++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->LowColor().GetColor32(); do { if (pattern->IsHighColor(x, y)) { @@ -82,7 +82,7 @@ blend_solid_hspan_erase(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->LowColor().GetColor32(); do { if (pattern->IsHighColor(x, y)) { @@ -108,7 +108,7 @@ blend_solid_vspan_erase(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->LowColor().GetColor32(); do { if (pattern->IsHighColor(x, y)) { @@ -135,7 +135,7 @@ blend_color_hspan_erase(int x, int y, unsigned len, agg_buffer* buffer, const PatternHandler* pattern) { // TODO: compare this with BView - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h index cfa8418212..769165e175 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h @@ -36,7 +36,7 @@ blend_pixel_invert(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { if (pattern->IsHighColor(x, y)) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (cover == 255) { ASSIGN_INVERT(p); } else { @@ -51,7 +51,7 @@ blend_hline_invert(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if(cover == 255) { do { if (pattern->IsHighColor(x, y)) { @@ -77,7 +77,7 @@ blend_solid_hspan_invert(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { if (pattern->IsHighColor(x, y)) { if (*covers) { @@ -102,7 +102,7 @@ blend_solid_vspan_invert(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { if (pattern->IsHighColor(x, y)) { if (*covers) { @@ -129,7 +129,7 @@ blend_color_hspan_invert(int x, int y, unsigned len, { // TODO: does the R5 app_server check for the // appearance of the high color in the source bitmap? - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMax.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMax.h index 983040ed80..d25e84223d 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMax.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMax.h @@ -40,7 +40,7 @@ void blend_pixel_max(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); if (cover == 255) { ASSIGN_MAX(p, color.red, color.green, color.blue); @@ -55,7 +55,7 @@ blend_hline_max(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (cover == 255) { do { rgb_color color = pattern->R5ColorAt(x, y); @@ -83,7 +83,7 @@ blend_solid_hspan_max(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -107,7 +107,7 @@ blend_solid_vspan_max(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -131,7 +131,7 @@ blend_color_hspan_max(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMin.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMin.h index d143b48cee..49015659df 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMin.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMin.h @@ -34,7 +34,7 @@ void blend_pixel_min(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); if (cover == 255) { ASSIGN_MIN(p, color.red, color.green, color.blue); @@ -49,7 +49,7 @@ blend_hline_min(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (cover == 255) { do { rgb_color color = pattern->R5ColorAt(x, y); @@ -77,7 +77,7 @@ blend_solid_hspan_min(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -101,7 +101,7 @@ blend_solid_vspan_min(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -125,7 +125,7 @@ blend_color_hspan_min(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h index 7e595911ee..009f64acd9 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h @@ -32,7 +32,7 @@ blend_pixel_over(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { if (pattern->IsHighColor(x, y)) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->HighColor().GetColor32(); if (cover == 255) { ASSIGN_OVER(p, color.red, color.green, color.blue); @@ -56,7 +56,7 @@ blend_hline_over(int x, int y, unsigned len, p8[1] = (uint8)color.green; p8[2] = (uint8)color.red; p8[3] = 255; - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { if (pattern->IsHighColor(x, y)) *p32 = v; @@ -64,7 +64,7 @@ blend_hline_over(int x, int y, unsigned len, x++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->HighColor().GetColor32(); do { if (pattern->IsHighColor(x, y)) { @@ -82,7 +82,7 @@ blend_solid_hspan_over(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->HighColor().GetColor32(); do { if (pattern->IsHighColor(x, y)) { @@ -108,7 +108,7 @@ blend_solid_vspan_over(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->HighColor().GetColor32(); do { if (pattern->IsHighColor(x, y)) { @@ -134,7 +134,7 @@ blend_color_hspan_over(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h index 4f4eb8ad34..2b9f6e4877 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h @@ -19,7 +19,7 @@ blend_pixel_over_solid(int x, int y, const color_type& c, uint8 cover, if (pattern->IsSolidLow()) return; - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (cover == 255) { ASSIGN_OVER(p, c.r, c.g, c.b); } else { @@ -43,14 +43,14 @@ blend_hline_over_solid(int x, int y, unsigned len, p8[1] = (uint8)c.g; p8[2] = (uint8)c.r; p8[3] = 255; - uint32* p32 = (uint32*)(buffer->row(y)) + x; + uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; do { *p32 = v; p32++; x++; } while(--len); } else { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { BLEND_OVER(p, c.r, c.g, c.b, cover); x++; @@ -68,7 +68,7 @@ blend_solid_hspan_over_solid(int x, int y, unsigned len, if (pattern->IsSolidLow()) return; - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { if (*covers) { if (*covers == 255) { @@ -94,7 +94,7 @@ blend_solid_vspan_over_solid(int x, int y, unsigned len, if (pattern->IsSolidLow()) return; - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { if (*covers) { if (*covers == 255) { @@ -117,7 +117,7 @@ blend_color_hspan_over_solid(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelect.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelect.h index 662bff7b7c..6a4a584579 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelect.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelect.h @@ -56,7 +56,7 @@ blend_pixel_select(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { if (pattern->IsHighColor(x, y)) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color high = pattern->HighColor().GetColor32(); rgb_color low = pattern->LowColor().GetColor32(); rgb_color color; @@ -76,7 +76,7 @@ blend_hline_select(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color high = pattern->HighColor().GetColor32(); rgb_color low = pattern->LowColor().GetColor32(); rgb_color color; @@ -106,7 +106,7 @@ blend_solid_hspan_select(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color high = pattern->HighColor().GetColor32(); rgb_color low = pattern->LowColor().GetColor32(); rgb_color color; @@ -134,7 +134,7 @@ blend_solid_vspan_select(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color high = pattern->HighColor().GetColor32(); rgb_color low = pattern->LowColor().GetColor32(); rgb_color color; @@ -162,7 +162,7 @@ blend_color_hspan_select(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color high = pattern->HighColor().GetColor32(); rgb_color low = pattern->LowColor().GetColor32(); rgb_color color; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtract.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtract.h index 6683c8ad88..ab900fdbe0 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtract.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtract.h @@ -42,7 +42,7 @@ void blend_pixel_subtract(int x, int y, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->R5ColorAt(x, y); if (cover == 255) { ASSIGN_SUBTRACT(p, color.red, color.green, color.blue); @@ -57,7 +57,7 @@ blend_hline_subtract(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (cover == 255) { do { rgb_color color = pattern->R5ColorAt(x, y); @@ -85,7 +85,7 @@ blend_solid_hspan_subtract(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -109,7 +109,7 @@ blend_solid_vspan_subtract(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->R5ColorAt(x, y); if (*covers) { @@ -133,7 +133,7 @@ blend_color_hspan_subtract(int x, int y, unsigned len, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { - uint8* p = buffer->row(y) + (x << 2); + uint8* p = buffer->row_ptr(y) + (x << 2); if (covers) { // non-solid opacity do { diff --git a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h index 4029e94111..b72c00f376 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h +++ b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h @@ -14,7 +14,7 @@ #define PIXEL_FORMAT_H #include -#include +#include #include #include @@ -25,6 +25,15 @@ class PixelFormat { public: typedef agg::rgba8 color_type; typedef agg::rendering_buffer agg_buffer; + typedef agg::rendering_buffer::row_data row_data; + typedef agg::order_bgra order_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 = 4, + }; typedef void (*blend_pixel_f)(int x, int y, const color_type& c, uint8 cover, @@ -65,41 +74,58 @@ class PixelFormat { { return fUsesOpCopyForText; } // AGG "pixel format" interface - unsigned width() const { return fBuffer->width(); } - unsigned height() const { return fBuffer->height(); } + inline unsigned width() const + { return fBuffer->width(); } + inline unsigned height() const + { return fBuffer->height(); } + inline int stride() const + { return fBuffer->stride(); } - void blend_pixel(int x, int y, + inline uint8* row_ptr(int y) + { return fBuffer->row_ptr(y); } + inline const uint8* row_ptr(int y) const + { return fBuffer->row_ptr(y); } + inline row_data row(int y) const + { return fBuffer->row(y); } + + inline uint8* pix_ptr(int x, int y); + inline const uint8* pix_ptr(int x, int y) const; + + inline static void make_pix(uint8* p, const color_type& c); +// inline color_type pixel(int x, int y) const; + + inline void blend_pixel(int x, int y, const color_type& c, uint8 cover); - void blend_hline(int x, int y, + inline void blend_hline(int x, int y, unsigned len, const color_type& c, uint8 cover); - void blend_vline(int x, int y, + inline void blend_vline(int x, int y, unsigned len, const color_type& c, uint8 cover); - void blend_solid_hspan(int x, int y, + inline void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const uint8* covers); - void blend_solid_vspan(int x, int y, + inline void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const uint8* covers); - void blend_color_hspan(int x, int y, + inline void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const uint8* covers, uint8 cover); - void blend_color_vspan(int x, int y, + inline void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const uint8* covers, @@ -121,6 +147,42 @@ class PixelFormat { // inlined functions +// pix_ptr +inline uint8* +PixelFormat::pix_ptr(int x, int y) +{ + return fBuffer->row_ptr(y) + x * pix_width; +} + +// pix_ptr +inline const uint8* +PixelFormat::pix_ptr(int x, int y) const +{ + return fBuffer->row_ptr(y) + x * pix_width; +} + +// make_pix +inline void +PixelFormat::make_pix(uint8* p, const color_type& c) +{ + p[0] = c.b; + p[1] = c.g; + p[2] = c.r; + p[3] = c.a; +} + +//// pixel +//inline color_type +//PixelFormat::pixel(int x, int y) const +//{ +// const uint8* p = (const uint8*)fBuffer->row_ptr(y); +// if (p) { +// p += x << 2; +// return color_type(p[2], p[1], p[0], p[3]); +// } +// return color_type::no_color(); +//} + // blend_pixel inline void PixelFormat::blend_pixel(int x, int y, const color_type& c, uint8 cover) diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp index 87521eb545..8acafedabf 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp @@ -223,7 +223,7 @@ AGGTextRenderer::RenderString(const char* string, // "glyphBounds" is the bounds of the glyph transformed // by the x y location of the glyph along the base line, // it is therefor yet "untransformed". - const agg::rect& r = glyph->bounds; + const agg::rect_i& r = glyph->bounds; BRect glyphBounds(r.x1 + x, r.y1 + y - 1, r.x2 + x + 1, r.y2 + y + 1); // NOTE: "-1"/"+1" converts the glyph bounding box from pixel // indices to pixel area coordinates diff --git a/src/servers/app/drawing/Painter/font_support/agg_font_freetype.cpp b/src/servers/app/drawing/Painter/font_support/agg_font_freetype.cpp index a593b585b1..0d67c695ea 100644 --- a/src/servers/app/drawing/Painter/font_support/agg_font_freetype.cpp +++ b/src/servers/app/drawing/Painter/font_support/agg_font_freetype.cpp @@ -336,7 +336,7 @@ namespace agg { const int8u* buf = (const int8u*)bitmap.buffer; int pitch = bitmap.pitch; sl.reset(x, x + bitmap.width); - storage.prepare(bitmap.width + 2); + storage.prepare(); if(flip_y) { buf += bitmap.pitch * (bitmap.rows - 1); @@ -377,7 +377,7 @@ namespace agg { const int8u* buf = (const int8u*)bitmap.buffer; int pitch = bitmap.pitch; sl.reset(x, x + bitmap.width); - storage.prepare(bitmap.width + 2); + storage.prepare(); if(flip_y) { buf += bitmap.pitch * (bitmap.rows - 1); @@ -865,12 +865,12 @@ namespace agg { conv_coord_none); m_rasterizer.add_path(m_curves16); } - m_scanlines_bin.prepare(1); // Remove all + m_scanlines_bin.prepare(); // Remove all render_scanlines(m_rasterizer, m_scanline_bin, m_scanlines_bin); m_bounds.x1 = m_scanlines_bin.min_x(); m_bounds.y1 = m_scanlines_bin.min_y(); - m_bounds.x2 = m_scanlines_bin.max_x(); - m_bounds.y2 = m_scanlines_bin.max_y(); + m_bounds.x2 = m_scanlines_bin.max_x() + 1; + m_bounds.y2 = m_scanlines_bin.max_y() + 1; m_data_size = m_scanlines_bin.byte_size(); m_data_type = glyph_data_mono; m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; @@ -902,12 +902,12 @@ namespace agg { conv_coord_none); m_rasterizer.add_path(m_curves16); } - m_scanlines_aa.prepare(1); // Remove all + m_scanlines_aa.prepare(); // Remove all render_scanlines(m_rasterizer, m_scanline_aa, m_scanlines_aa); m_bounds.x1 = m_scanlines_aa.min_x(); m_bounds.y1 = m_scanlines_aa.min_y(); - m_bounds.x2 = m_scanlines_aa.max_x(); - m_bounds.y2 = m_scanlines_aa.max_y(); + m_bounds.x2 = m_scanlines_aa.max_x() + 1; + m_bounds.y2 = m_scanlines_aa.max_y() + 1; m_data_size = m_scanlines_aa.byte_size(); m_data_type = glyph_data_gray8; m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; diff --git a/src/servers/app/drawing/Painter/font_support/agg_font_freetype.h b/src/servers/app/drawing/Painter/font_support/agg_font_freetype.h index ce1e2402d8..95c2e395fa 100644 --- a/src/servers/app/drawing/Painter/font_support/agg_font_freetype.h +++ b/src/servers/app/drawing/Painter/font_support/agg_font_freetype.h @@ -95,7 +95,7 @@ namespace agg unsigned glyph_index() const { return m_glyph_index; } unsigned data_size() const { return m_data_size; } glyph_data_type data_type() const { return m_data_type; } - const rect& bounds() const { return m_bounds; } + const rect_i& bounds() const { return m_bounds; } double advance_x() const { return m_advance_x; } double advance_y() const { return m_advance_y; } void write_glyph_to(int8u* data) const; @@ -129,7 +129,7 @@ namespace agg unsigned m_glyph_index; unsigned m_data_size; glyph_data_type m_data_type; - rect m_bounds; + rect_i m_bounds; double m_advance_x; double m_advance_y;