From 2ca8fcbc8a7a3ef6adfac154c47068c1696205d0 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Tue, 16 Jun 2015 16:29:44 -0700 Subject: Separate agg-authored code from fx-authored code. Creates a separate library so we can apply less-strict warnings to the code we can't change from upstream vs. the code we can change, reducing noise in the standalone build. Remove needless foo.{cpp,h} files that merely perform indirection via #include "some_other_path/foo.{cpp,h}". BUG=pdfium:166 R=brucedawson@chromium.org, thestig@chromium.org Review URL: https://codereview.chromium.org/1152743007. --- BUILD.gn | 20 +- core/src/fxge/agg/DEPS | 3 + core/src/fxge/agg/agg23/agg_array.h | 506 ------ core/src/fxge/agg/agg23/agg_basics.h | 282 ---- core/src/fxge/agg/agg23/agg_clip_liang_barsky.h | 125 -- core/src/fxge/agg/agg23/agg_color_gray.h | 50 - core/src/fxge/agg/agg23/agg_conv_adaptor_vcgen.h | 138 -- core/src/fxge/agg/agg23/agg_conv_dash.h | 61 - core/src/fxge/agg/agg23/agg_conv_stroke.h | 110 -- core/src/fxge/agg/agg23/agg_curves.h | 188 --- core/src/fxge/agg/agg23/agg_math.h | 63 - core/src/fxge/agg/agg23/agg_math_stroke.h | 272 ---- core/src/fxge/agg/agg23/agg_path_storage.h | 172 --- core/src/fxge/agg/agg23/agg_pixfmt_gray.h | 177 --- .../fxge/agg/agg23/agg_rasterizer_scanline_aa.h | 472 ------ core/src/fxge/agg/agg23/agg_render_scanlines.h | 50 - core/src/fxge/agg/agg23/agg_renderer_base.h | 163 -- core/src/fxge/agg/agg23/agg_renderer_scanline.h | 93 -- core/src/fxge/agg/agg23/agg_rendering_buffer.h | 145 -- core/src/fxge/agg/agg23/agg_scanline_u.h | 150 -- core/src/fxge/agg/agg23/agg_shorten_path.h | 57 - core/src/fxge/agg/agg23/agg_vcgen_dash.h | 75 - core/src/fxge/agg/agg23/agg_vcgen_stroke.h | 120 -- core/src/fxge/agg/agg23/agg_vertex_sequence.h | 100 -- core/src/fxge/agg/agg23/fx_agg_curves.cpp | 109 -- core/src/fxge/agg/agg23/fx_agg_driver.cpp | 1610 -------------------- core/src/fxge/agg/agg23/fx_agg_path_storage.cpp | 98 -- .../agg/agg23/fx_agg_rasterizer_scanline_aa.cpp | 489 ------ core/src/fxge/agg/agg23/fx_agg_vcgen_dash.cpp | 176 --- core/src/fxge/agg/agg23/fx_agg_vcgen_stroke.cpp | 214 --- core/src/fxge/agg/include/fx_agg_driver.h | 5 +- core/src/fxge/agg/include/fxfx_agg_basics.h | 12 - .../fxge/agg/include/fxfx_agg_clip_liang_barsky.h | 12 - core/src/fxge/agg/include/fxfx_agg_conv_dash.h | 12 - core/src/fxge/agg/include/fxfx_agg_conv_stroke.h | 12 - core/src/fxge/agg/include/fxfx_agg_curves.h | 12 - core/src/fxge/agg/include/fxfx_agg_path_storage.h | 12 - .../agg/include/fxfx_agg_rasterizer_scanline_aa.h | 12 - .../fxge/agg/include/fxfx_agg_renderer_scanline.h | 12 - .../fxge/agg/include/fxfx_agg_rendering_buffer.h | 12 - core/src/fxge/agg/include/fxfx_agg_scanline_u.h | 12 - core/src/fxge/agg/src/fx_agg_driver.cpp | 1610 ++++++++++++++++++++ core/src/fxge/agg/src/fxfx_agg_curves.cpp | 7 - core/src/fxge/agg/src/fxfx_agg_driver.cpp | 7 - core/src/fxge/agg/src/fxfx_agg_path_storage.cpp | 7 - .../agg/src/fxfx_agg_rasterizer_scanline_aa.cpp | 7 - core/src/fxge/agg/src/fxfx_agg_vcgen_dash.cpp | 7 - core/src/fxge/agg/src/fxfx_agg_vcgen_stroke.cpp | 7 - core/src/fxge/apple/fx_apple_platform.cpp | 17 +- core/src/fxge/apple/fx_quartz_device.cpp | 10 +- core/src/fxge/ge/fx_ge_linux.cpp | 3 +- core/src/fxge/win32/fx_win32_device.cpp | 19 +- pdfium.gyp | 24 +- third_party/BUILD.gn | 25 + third_party/agg23/agg_array.h | 506 ++++++ third_party/agg23/agg_basics.h | 282 ++++ third_party/agg23/agg_clip_liang_barsky.h | 125 ++ third_party/agg23/agg_color_gray.h | 50 + third_party/agg23/agg_conv_adaptor_vcgen.h | 138 ++ third_party/agg23/agg_conv_dash.h | 61 + third_party/agg23/agg_conv_stroke.h | 110 ++ third_party/agg23/agg_curves.cpp | 109 ++ third_party/agg23/agg_curves.h | 188 +++ third_party/agg23/agg_math.h | 63 + third_party/agg23/agg_math_stroke.h | 272 ++++ third_party/agg23/agg_path_storage.cpp | 98 ++ third_party/agg23/agg_path_storage.h | 172 +++ third_party/agg23/agg_pixfmt_gray.h | 177 +++ third_party/agg23/agg_rasterizer_scanline_aa.cpp | 489 ++++++ third_party/agg23/agg_rasterizer_scanline_aa.h | 472 ++++++ third_party/agg23/agg_render_scanlines.h | 50 + third_party/agg23/agg_renderer_base.h | 163 ++ third_party/agg23/agg_renderer_scanline.h | 93 ++ third_party/agg23/agg_rendering_buffer.h | 145 ++ third_party/agg23/agg_scanline_u.h | 150 ++ third_party/agg23/agg_shorten_path.h | 57 + third_party/agg23/agg_vcgen_dash.cpp | 176 +++ third_party/agg23/agg_vcgen_dash.h | 75 + third_party/agg23/agg_vcgen_stroke.cpp | 214 +++ third_party/agg23/agg_vcgen_stroke.h | 120 ++ third_party/agg23/agg_vertex_sequence.h | 100 ++ third_party/third_party.gyp | 27 + 82 files changed, 6361 insertions(+), 6484 deletions(-) create mode 100644 core/src/fxge/agg/DEPS delete mode 100644 core/src/fxge/agg/agg23/agg_array.h delete mode 100644 core/src/fxge/agg/agg23/agg_basics.h delete mode 100644 core/src/fxge/agg/agg23/agg_clip_liang_barsky.h delete mode 100644 core/src/fxge/agg/agg23/agg_color_gray.h delete mode 100644 core/src/fxge/agg/agg23/agg_conv_adaptor_vcgen.h delete mode 100644 core/src/fxge/agg/agg23/agg_conv_dash.h delete mode 100644 core/src/fxge/agg/agg23/agg_conv_stroke.h delete mode 100644 core/src/fxge/agg/agg23/agg_curves.h delete mode 100644 core/src/fxge/agg/agg23/agg_math.h delete mode 100644 core/src/fxge/agg/agg23/agg_math_stroke.h delete mode 100644 core/src/fxge/agg/agg23/agg_path_storage.h delete mode 100644 core/src/fxge/agg/agg23/agg_pixfmt_gray.h delete mode 100644 core/src/fxge/agg/agg23/agg_rasterizer_scanline_aa.h delete mode 100644 core/src/fxge/agg/agg23/agg_render_scanlines.h delete mode 100644 core/src/fxge/agg/agg23/agg_renderer_base.h delete mode 100644 core/src/fxge/agg/agg23/agg_renderer_scanline.h delete mode 100644 core/src/fxge/agg/agg23/agg_rendering_buffer.h delete mode 100644 core/src/fxge/agg/agg23/agg_scanline_u.h delete mode 100644 core/src/fxge/agg/agg23/agg_shorten_path.h delete mode 100644 core/src/fxge/agg/agg23/agg_vcgen_dash.h delete mode 100644 core/src/fxge/agg/agg23/agg_vcgen_stroke.h delete mode 100644 core/src/fxge/agg/agg23/agg_vertex_sequence.h delete mode 100644 core/src/fxge/agg/agg23/fx_agg_curves.cpp delete mode 100644 core/src/fxge/agg/agg23/fx_agg_driver.cpp delete mode 100644 core/src/fxge/agg/agg23/fx_agg_path_storage.cpp delete mode 100644 core/src/fxge/agg/agg23/fx_agg_rasterizer_scanline_aa.cpp delete mode 100644 core/src/fxge/agg/agg23/fx_agg_vcgen_dash.cpp delete mode 100644 core/src/fxge/agg/agg23/fx_agg_vcgen_stroke.cpp delete mode 100644 core/src/fxge/agg/include/fxfx_agg_basics.h delete mode 100644 core/src/fxge/agg/include/fxfx_agg_clip_liang_barsky.h delete mode 100644 core/src/fxge/agg/include/fxfx_agg_conv_dash.h delete mode 100644 core/src/fxge/agg/include/fxfx_agg_conv_stroke.h delete mode 100644 core/src/fxge/agg/include/fxfx_agg_curves.h delete mode 100644 core/src/fxge/agg/include/fxfx_agg_path_storage.h delete mode 100644 core/src/fxge/agg/include/fxfx_agg_rasterizer_scanline_aa.h delete mode 100644 core/src/fxge/agg/include/fxfx_agg_renderer_scanline.h delete mode 100644 core/src/fxge/agg/include/fxfx_agg_rendering_buffer.h delete mode 100644 core/src/fxge/agg/include/fxfx_agg_scanline_u.h create mode 100644 core/src/fxge/agg/src/fx_agg_driver.cpp delete mode 100644 core/src/fxge/agg/src/fxfx_agg_curves.cpp delete mode 100644 core/src/fxge/agg/src/fxfx_agg_driver.cpp delete mode 100644 core/src/fxge/agg/src/fxfx_agg_path_storage.cpp delete mode 100644 core/src/fxge/agg/src/fxfx_agg_rasterizer_scanline_aa.cpp delete mode 100644 core/src/fxge/agg/src/fxfx_agg_vcgen_dash.cpp delete mode 100644 core/src/fxge/agg/src/fxfx_agg_vcgen_stroke.cpp create mode 100644 third_party/agg23/agg_array.h create mode 100644 third_party/agg23/agg_basics.h create mode 100644 third_party/agg23/agg_clip_liang_barsky.h create mode 100644 third_party/agg23/agg_color_gray.h create mode 100644 third_party/agg23/agg_conv_adaptor_vcgen.h create mode 100644 third_party/agg23/agg_conv_dash.h create mode 100644 third_party/agg23/agg_conv_stroke.h create mode 100644 third_party/agg23/agg_curves.cpp create mode 100644 third_party/agg23/agg_curves.h create mode 100644 third_party/agg23/agg_math.h create mode 100644 third_party/agg23/agg_math_stroke.h create mode 100644 third_party/agg23/agg_path_storage.cpp create mode 100644 third_party/agg23/agg_path_storage.h create mode 100644 third_party/agg23/agg_pixfmt_gray.h create mode 100644 third_party/agg23/agg_rasterizer_scanline_aa.cpp create mode 100644 third_party/agg23/agg_rasterizer_scanline_aa.h create mode 100644 third_party/agg23/agg_render_scanlines.h create mode 100644 third_party/agg23/agg_renderer_base.h create mode 100644 third_party/agg23/agg_renderer_scanline.h create mode 100644 third_party/agg23/agg_rendering_buffer.h create mode 100644 third_party/agg23/agg_scanline_u.h create mode 100644 third_party/agg23/agg_shorten_path.h create mode 100644 third_party/agg23/agg_vcgen_dash.cpp create mode 100644 third_party/agg23/agg_vcgen_dash.h create mode 100644 third_party/agg23/agg_vcgen_stroke.cpp create mode 100644 third_party/agg23/agg_vcgen_stroke.h create mode 100644 third_party/agg23/agg_vertex_sequence.h diff --git a/BUILD.gn b/BUILD.gn index 54e9594229..d0f2920c99 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -558,6 +558,9 @@ static_library("fxcrt") { } static_library("fxge") { + deps = [ + "third_party:fx_agg", + ] sources = [ "core/include/fxge/fpf.h", "core/include/fxge/fx_dib.h", @@ -567,22 +570,7 @@ static_library("fxge") { "core/include/fxge/fx_ge_apple.h", "core/include/fxge/fx_ge_win32.h", "core/src/fxge/agg/include/fx_agg_driver.h", - "core/src/fxge/agg/include/fxfx_agg_basics.h", - "core/src/fxge/agg/include/fxfx_agg_clip_liang_barsky.h", - "core/src/fxge/agg/include/fxfx_agg_conv_dash.h", - "core/src/fxge/agg/include/fxfx_agg_conv_stroke.h", - "core/src/fxge/agg/include/fxfx_agg_curves.h", - "core/src/fxge/agg/include/fxfx_agg_path_storage.h", - "core/src/fxge/agg/include/fxfx_agg_rasterizer_scanline_aa.h", - "core/src/fxge/agg/include/fxfx_agg_renderer_scanline.h", - "core/src/fxge/agg/include/fxfx_agg_rendering_buffer.h", - "core/src/fxge/agg/include/fxfx_agg_scanline_u.h", - "core/src/fxge/agg/src/fxfx_agg_curves.cpp", - "core/src/fxge/agg/src/fxfx_agg_driver.cpp", - "core/src/fxge/agg/src/fxfx_agg_path_storage.cpp", - "core/src/fxge/agg/src/fxfx_agg_rasterizer_scanline_aa.cpp", - "core/src/fxge/agg/src/fxfx_agg_vcgen_dash.cpp", - "core/src/fxge/agg/src/fxfx_agg_vcgen_stroke.cpp", + "core/src/fxge/agg/src/fx_agg_driver.cpp", "core/src/fxge/android/fpf_skiafont.cpp", "core/src/fxge/android/fpf_skiafont.h", "core/src/fxge/android/fpf_skiafontmgr.cpp", diff --git a/core/src/fxge/agg/DEPS b/core/src/fxge/agg/DEPS new file mode 100644 index 0000000000..25d9e110e6 --- /dev/null +++ b/core/src/fxge/agg/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + '+third_party/agg23', +] diff --git a/core/src/fxge/agg/agg23/agg_array.h b/core/src/fxge/agg/agg23/agg_array.h deleted file mode 100644 index 810eb4ef22..0000000000 --- a/core/src/fxge/agg/agg23/agg_array.h +++ /dev/null @@ -1,506 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -#ifndef AGG_ARRAY_INCLUDED -#define AGG_ARRAY_INCLUDED -#include "agg_basics.h" -namespace agg -{ -template class pod_array -{ -public: - typedef T value_type; - ~pod_array() - { - FX_Free(m_array); - } - pod_array() : m_size(0), m_capacity(0), m_array(0) {} - pod_array(unsigned cap, unsigned extra_tail = 0); - pod_array(const pod_array&); - const pod_array& operator = (const pod_array&); - void capacity(unsigned cap, unsigned extra_tail = 0); - unsigned capacity() const - { - return m_capacity; - } - void allocate(unsigned size, unsigned extra_tail = 0); - void resize(unsigned new_size); - void zero() - { - FXSYS_memset(m_array, 0, sizeof(T) * m_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); - } - 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 cut_at(unsigned num) - { - if(num < m_size) { - m_size = num; - } - } -private: - unsigned m_size; - unsigned m_capacity; - T* m_array; -}; -template -void pod_array::capacity(unsigned cap, unsigned extra_tail) -{ - m_size = 0; - unsigned full_cap = cap + extra_tail; - if(full_cap < cap) { - FX_Free(m_array); - m_array = 0; - m_capacity = 0; - } else if(full_cap > m_capacity) { - FX_Free(m_array); - m_array = FX_Alloc(T, full_cap); - m_capacity = full_cap; - } -} -template -void pod_array::allocate(unsigned size, unsigned extra_tail) -{ - capacity(size, extra_tail); - m_size = size; -} -template -void pod_array::resize(unsigned new_size) -{ - if(new_size > m_size) { - if(new_size > m_capacity) { - T* data = FX_Alloc(T, new_size); - FXSYS_memcpy(data, m_array, m_size * sizeof(T)); - FX_Free(m_array); - m_array = data; - } - } else { - m_size = new_size; - } -} -template pod_array::pod_array(unsigned cap, unsigned extra_tail) : - m_size(0), m_capacity(cap + extra_tail), m_array(FX_Alloc(T, m_capacity)) {} -template pod_array::pod_array(const pod_array& v) : - m_size(v.m_size), - m_capacity(v.m_capacity), - m_array(v.m_capacity ? FX_Alloc(T, v.m_capacity) : 0) -{ - FXSYS_memcpy(m_array, v.m_array, sizeof(T) * v.m_size); -} -template const pod_array& -pod_array::operator = (const pod_array&v) -{ - allocate(v.m_size); - if(v.m_size) { - FXSYS_memcpy(m_array, v.m_array, sizeof(T) * v.m_size); - } - return *this; -} -template class pod_deque -{ -public: - enum block_scale_e { - block_shift = S, - block_size = 1 << block_shift, - block_mask = block_size - 1 - }; - typedef T value_type; - ~pod_deque(); - pod_deque(); - pod_deque(unsigned block_ptr_inc); - pod_deque(const pod_deque& v); - const pod_deque& operator = (const pod_deque& v); - void remove_all() - { - m_size = 0; - } - void free_all() - { - free_tail(0); - } - void free_tail(unsigned size); - void add(const T& val); - void modify_last(const T& val); - void remove_last(); - int allocate_continuous_block(unsigned num_elements); - void add_array(const T* ptr, unsigned num_elem) - { - while(num_elem--) { - add(*ptr++); - } - } - template void add_data(DataAccessor& data) - { - while(data.size()) { - add(*data); - ++data; - } - } - void cut_at(unsigned size) - { - if(size < m_size) { - m_size = size; - } - } - unsigned size() const - { - return m_size; - } - const T& operator [] (unsigned i) const - { - return m_blocks[i >> block_shift][i & block_mask]; - } - T& operator [] (unsigned i) - { - 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 - { - return (*this)[idx]; - } - T& curr(unsigned idx) - { - return (*this)[idx]; - } - const T& prev(unsigned idx) const - { - return (*this)[(idx + m_size - 1) % m_size]; - } - T& prev(unsigned idx) - { - return (*this)[(idx + m_size - 1) % m_size]; - } - const T& next(unsigned idx) const - { - return (*this)[(idx + 1) % m_size]; - } - T& next(unsigned idx) - { - return (*this)[(idx + 1) % m_size]; - } - const T& last() const - { - return (*this)[m_size - 1]; - } - T& last() - { - return (*this)[m_size - 1]; - } - unsigned byte_size() const; - const T* block(unsigned nb) const - { - return m_blocks[nb]; - } -public: - void allocate_block(unsigned nb); - T* data_ptr(); - unsigned m_size; - unsigned m_num_blocks; - unsigned m_max_blocks; - T** m_blocks; - unsigned m_block_ptr_inc; -}; -template pod_deque::~pod_deque() -{ - if(m_num_blocks) { - T** blk = m_blocks + m_num_blocks - 1; - while(m_num_blocks--) { - FX_Free(*blk); - --blk; - } - FX_Free(m_blocks); - } -} -template -void pod_deque::free_tail(unsigned size) -{ - if(size < m_size) { - unsigned nb = (size + block_mask) >> block_shift; - while(m_num_blocks > nb) { - FX_Free(m_blocks[--m_num_blocks]); - } - m_size = size; - } -} -template pod_deque::pod_deque() : - m_size(0), - m_num_blocks(0), - m_max_blocks(0), - m_blocks(0), - m_block_ptr_inc(block_size) -{ -} -template -pod_deque::pod_deque(unsigned block_ptr_inc) : - m_size(0), - m_num_blocks(0), - m_max_blocks(0), - m_blocks(0), - m_block_ptr_inc(block_ptr_inc) -{ -} -template -pod_deque::pod_deque(const pod_deque& 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 ? FX_Alloc(T*, 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] = FX_Alloc(T, block_size); - FXSYS_memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); - } -} -template -const pod_deque& pod_deque::operator = (const pod_deque& v) -{ - unsigned i; - for(i = m_num_blocks; i < v.m_num_blocks; ++i) { - allocate_block(i); - } - for(i = 0; i < v.m_num_blocks; ++i) { - FXSYS_memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); - } - m_size = v.m_size; - return *this; -} -template -void pod_deque::allocate_block(unsigned nb) -{ - if(nb >= m_max_blocks) { - T** new_blocks = FX_Alloc(T*, m_max_blocks + m_block_ptr_inc); - if(m_blocks) { - FXSYS_memcpy(new_blocks, - m_blocks, - m_num_blocks * sizeof(T*)); - FX_Free(m_blocks); - } - m_blocks = new_blocks; - m_max_blocks += m_block_ptr_inc; - } - m_blocks[nb] = FX_Alloc(T, block_size); - m_num_blocks++; -} -template -inline T* pod_deque::data_ptr() -{ - unsigned nb = m_size >> block_shift; - if(nb >= m_num_blocks) { - allocate_block(nb); - } - return m_blocks[nb] + (m_size & block_mask); -} -template -inline void pod_deque::add(const T& val) -{ - *data_ptr() = val; - ++m_size; -} -template -inline void pod_deque::remove_last() -{ - if(m_size) { - --m_size; - } -} -template -void pod_deque::modify_last(const T& val) -{ - remove_last(); - add(val); -} -template -int pod_deque::allocate_continuous_block(unsigned num_elements) -{ - if(num_elements < block_size) { - data_ptr(); - unsigned rest = block_size - (m_size & block_mask); - unsigned index; - if(num_elements <= rest) { - index = m_size; - m_size += num_elements; - return index; - } - m_size += rest; - data_ptr(); - index = m_size; - m_size += num_elements; - return index; - } - return -1; -} -template -unsigned pod_deque::byte_size() const -{ - return m_size * sizeof(T); -} -class pod_allocator -{ -public: - void remove_all() - { - if(m_num_blocks) { - int8u** blk = m_blocks + m_num_blocks - 1; - while(m_num_blocks--) { - FX_Free(*blk); - --blk; - } - FX_Free(m_blocks); - } - m_num_blocks = 0; - m_max_blocks = 0; - m_blocks = 0; - m_buf_ptr = 0; - m_rest = 0; - } - ~pod_allocator() - { - remove_all(); - } - pod_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), - m_max_blocks(0), - m_blocks(0), - m_buf_ptr(0), - m_rest(0) - { - } - int8u* allocate(unsigned size, unsigned alignment = 1) - { - if(size == 0) { - return 0; - } - if(size <= m_rest) { - int8u* ptr = m_buf_ptr; - if(alignment > 1) { - unsigned align = (alignment - unsigned((size_t)ptr) % alignment) % alignment; - size += align; - ptr += align; - if(size <= m_rest) { - m_rest -= size; - m_buf_ptr += size; - return ptr; - } - allocate_block(size); - return allocate(size - align, alignment); - } - m_rest -= size; - m_buf_ptr += size; - return ptr; - } - allocate_block(size + alignment - 1); - return allocate(size, alignment); - } -private: - void allocate_block(unsigned size) - { - if(size < m_block_size) { - size = m_block_size; - } - if(m_num_blocks >= m_max_blocks) { - int8u** new_blocks = FX_Alloc(int8u*, m_max_blocks + m_block_ptr_inc); - if(m_blocks) { - FXSYS_memcpy(new_blocks, - m_blocks, - m_num_blocks * sizeof(int8u*)); - FX_Free(m_blocks); - } - m_blocks = new_blocks; - m_max_blocks += m_block_ptr_inc; - } - m_blocks[m_num_blocks] = m_buf_ptr = FX_Alloc(int8u, 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; -}; -enum quick_sort_threshold_e { - quick_sort_threshold = 9 -}; -template inline void swap_elements(T& a, T& b) -{ - T temp = a; - a = b; - b = temp; -} -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_basics.h b/core/src/fxge/agg/agg23/agg_basics.h deleted file mode 100644 index d2fad58feb..0000000000 --- a/core/src/fxge/agg/agg23/agg_basics.h +++ /dev/null @@ -1,282 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -#ifndef AGG_BASICS_INCLUDED -#define AGG_BASICS_INCLUDED -#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 -#define AGG_INT64 signed long long -#endif -#ifndef AGG_INT64U -#define AGG_INT64U unsigned long long -#endif -#define AGG_INLINE inline -namespace agg -{ -typedef AGG_INT8 int8; -typedef AGG_INT8U int8u; -typedef AGG_INT16 int16; -typedef AGG_INT16U int16u; -typedef AGG_INT32 int32; -typedef AGG_INT32U int32u; -typedef AGG_INT64 int64; -typedef AGG_INT64U int64u; -typedef unsigned char cover_type; -enum cover_scale_e { - cover_shift = 8, - cover_size = 1 << cover_shift, - cover_mask = cover_size - 1, - cover_none = 0, - cover_full = cover_mask -}; -template struct rect_base { - typedef rect_base self_type; - T x1; - T y1; - T x2; - T y2; - rect_base() {} - rect_base(T x1_, T y1_, T x2_, T y2_) : - x1(x1_), y1(y1_), x2(x2_), y2(y2_) {} - const self_type& normalize() - { - T t; - if(x1 > x2) { - t = x1; - x1 = x2; - x2 = t; - } - if(y1 > y2) { - t = y1; - y1 = y2; - y2 = t; - } - return *this; - } - bool clip(const self_type& r) - { - if(x2 > r.x2) { - x2 = r.x2; - } - if(y2 > r.y2) { - y2 = r.y2; - } - if(x1 < r.x1) { - x1 = r.x1; - } - if(y1 < r.y1) { - y1 = r.y1; - } - return x1 <= x2 && y1 <= y2; - } - bool is_valid() const - { - return x1 <= x2 && y1 <= y2; - } -}; -template -inline Rect intersect_rectangles(const Rect& r1, const Rect& r2) -{ - Rect r = r1; - if(r.x2 > r2.x2) { - r.x2 = r2.x2; - } - if(r.y2 > r2.y2) { - r.y2 = r2.y2; - } - if(r.x1 < r2.x1) { - r.x1 = r2.x1; - } - if(r.y1 < r2.y1) { - r.y1 = r2.y1; - } - return r; -} -template -inline Rect unite_rectangles(const Rect& r1, const Rect& r2) -{ - Rect r = r1; - if(r.x2 < r2.x2) { - r.x2 = r2.x2; - } - if(r.y2 < r2.y2) { - r.y2 = r2.y2; - } - if(r.x1 > r2.x1) { - r.x1 = r2.x1; - } - if(r.y1 > r2.y1) { - r.y1 = r2.y1; - } - return r; -} -typedef rect_base rect; -typedef rect_base rect_d; -enum path_commands_e { - path_cmd_stop = 0, - path_cmd_move_to = 1, - path_cmd_line_to = 2, - path_cmd_curve3 = 3, - path_cmd_curve4 = 4, - path_cmd_curveN = 5, - path_cmd_catrom = 6, - path_cmd_ubspline = 7, - path_cmd_end_poly = 0x0F, - path_cmd_mask = 0x0F -}; -enum path_flags_e { - path_flags_none = 0, - path_flags_ccw = 0x10, - path_flags_cw = 0x20, - path_flags_close = 0x40, - path_flags_jr = 0x80, - path_flags_mask = 0xF0 -}; -inline bool is_vertex(unsigned c) -{ - c &= ~path_flags_jr; - return c >= path_cmd_move_to && c < path_cmd_end_poly; -} -inline bool is_drawing(unsigned c) -{ - c &= ~path_flags_jr; - return c >= path_cmd_line_to && c < path_cmd_end_poly; -} -inline bool is_stop(unsigned c) -{ - c &= ~path_flags_jr; - return c == path_cmd_stop; -} -inline bool is_move_to(unsigned c) -{ - c &= ~path_flags_jr; - return c == path_cmd_move_to; -} -inline bool is_line_to(unsigned c) -{ - c &= ~path_flags_jr; - return c == path_cmd_line_to; -} -inline bool is_curve(unsigned c) -{ - c &= ~path_flags_jr; - return c == path_cmd_curve3 || c == path_cmd_curve4; -} -inline bool is_curve3(unsigned c) -{ - c &= ~path_flags_jr; - return c == path_cmd_curve3; -} -inline bool is_curve4(unsigned c) -{ - c &= ~path_flags_jr; - return c == path_cmd_curve4; -} -inline bool is_end_poly(unsigned c) -{ - c &= ~path_flags_jr; - return (c & path_cmd_mask) == path_cmd_end_poly; -} -inline bool is_close(unsigned c) -{ - c &= ~path_flags_jr; - return (c & ~(path_flags_cw | path_flags_ccw)) == - (path_cmd_end_poly | path_flags_close); -} -inline bool is_next_poly(unsigned c) -{ - c &= ~path_flags_jr; - return is_stop(c) || is_move_to(c) || is_end_poly(c); -} -inline bool is_cw(unsigned c) -{ - c &= ~path_flags_jr; - return (c & path_flags_cw) != 0; -} -inline bool is_ccw(unsigned c) -{ - c &= ~path_flags_jr; - return (c & path_flags_ccw) != 0; -} -inline bool is_oriented(unsigned c) -{ - c &= ~path_flags_jr; - return (c & (path_flags_cw | path_flags_ccw)) != 0; -} -inline bool is_closed(unsigned c) -{ - c &= ~path_flags_jr; - return (c & path_flags_close) != 0; -} -inline unsigned get_close_flag(unsigned c) -{ - c &= ~path_flags_jr; - return c & path_flags_close; -} -inline unsigned clear_orientation(unsigned c) -{ - c &= ~path_flags_jr; - return c & ~(path_flags_cw | path_flags_ccw); -} -inline unsigned get_orientation(unsigned c) -{ - c &= ~path_flags_jr; - return c & (path_flags_cw | path_flags_ccw); -} -inline unsigned set_orientation(unsigned c, unsigned o) -{ - c &= ~path_flags_jr; - return clear_orientation(c) | o; -} -struct point_type { - FX_FLOAT x, y; - unsigned flag; - point_type() {} - point_type(FX_FLOAT x_, FX_FLOAT y_, unsigned flag_ = 0) : x(x_), y(y_), flag(flag_) {} -}; -struct point_type_flag : public point_type { - unsigned flag; - point_type_flag() - { - flag = 0; - } - point_type_flag(FX_FLOAT x_, FX_FLOAT y_, unsigned flag_ = 0) : point_type(x_, y_), flag(flag_) {} -}; -struct vertex_type { - FX_FLOAT x, y; - unsigned cmd; - vertex_type() {} - vertex_type(FX_FLOAT x_, FX_FLOAT y_, unsigned cmd_) : - x(x_), y(y_), cmd(cmd_) {} -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_clip_liang_barsky.h b/core/src/fxge/agg/agg23/agg_clip_liang_barsky.h deleted file mode 100644 index cfc4c91f60..0000000000 --- a/core/src/fxge/agg/agg23/agg_clip_liang_barsky.h +++ /dev/null @@ -1,125 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Liang-Barsky clipping -// -//---------------------------------------------------------------------------- -#ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED -#define AGG_CLIP_LIANG_BARSKY_INCLUDED -#include "agg_basics.h" -namespace agg -{ -template -inline unsigned clipping_flags(T x, T y, const rect_base& clip_box) -{ - return (x > clip_box.x2) | - ((y > clip_box.y2) << 1) | - ((x < clip_box.x1) << 2) | - ((y < clip_box.y1) << 3); -} -template -inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2, - const rect_base& clip_box, - T* x, T* y) -{ - const FX_FLOAT nearzero = 1e-30f; - FX_FLOAT deltax = (FX_FLOAT)(x2 - x1); - FX_FLOAT deltay = (FX_FLOAT)(y2 - y1); - unsigned np = 0; - if(deltax == 0) { - deltax = (x1 > clip_box.x1) ? -nearzero : nearzero; - } - FX_FLOAT xin, xout; - if(deltax > 0) { - xin = (FX_FLOAT)clip_box.x1; - xout = (FX_FLOAT)clip_box.x2; - } else { - xin = (FX_FLOAT)clip_box.x2; - xout = (FX_FLOAT)clip_box.x1; - } - FX_FLOAT tinx = FXSYS_Div(xin - x1, deltax); - if(deltay == 0) { - deltay = (y1 > clip_box.y1) ? -nearzero : nearzero; - } - FX_FLOAT yin, yout; - if(deltay > 0) { - yin = (FX_FLOAT)clip_box.y1; - yout = (FX_FLOAT)clip_box.y2; - } else { - yin = (FX_FLOAT)clip_box.y2; - yout = (FX_FLOAT)clip_box.y1; - } - FX_FLOAT tiny = FXSYS_Div(yin - y1, deltay); - FX_FLOAT tin1, tin2; - if (tinx < tiny) { - tin1 = tinx; - tin2 = tiny; - } else { - tin1 = tiny; - tin2 = tinx; - } - if(tin1 <= 1.0f) { - if(0 < tin1) { - *x++ = (T)xin; - *y++ = (T)yin; - ++np; - } - if(tin2 <= 1.0f) { - FX_FLOAT toutx = FXSYS_Div(xout - x1, deltax); - FX_FLOAT touty = FXSYS_Div(yout - y1, deltay); - FX_FLOAT tout1 = (toutx < touty) ? toutx : touty; - if(tin2 > 0 || tout1 > 0) { - if(tin2 <= tout1) { - if(tin2 > 0) { - if(tinx > tiny) { - *x++ = (T)xin; - *y++ = (T)(y1 + FXSYS_Mul(deltay, tinx)); - } else { - *x++ = (T)(x1 + FXSYS_Mul(deltax, tiny)); - *y++ = (T)yin; - } - ++np; - } - if(tout1 < 1.0f) { - if(toutx < touty) { - *x++ = (T)xout; - *y++ = (T)(y1 + FXSYS_Mul(deltay, toutx)); - } else { - *x++ = (T)(x1 + FXSYS_Mul(deltax, touty)); - *y++ = (T)yout; - } - } else { - *x++ = x2; - *y++ = y2; - } - ++np; - } else { - if(tinx > tiny) { - *x++ = (T)xin; - *y++ = (T)yout; - } else { - *x++ = (T)xout; - *y++ = (T)yin; - } - ++np; - } - } - } - } - return np; -} -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_color_gray.h b/core/src/fxge/agg/agg23/agg_color_gray.h deleted file mode 100644 index 5db7bcaf28..0000000000 --- a/core/src/fxge/agg/agg23/agg_color_gray.h +++ /dev/null @@ -1,50 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// 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" -namespace agg -{ -struct gray8 { - typedef int8u value_type; - typedef int32u calc_type; - typedef int32 long_type; - enum base_scale_e { - base_shift = 8, - base_size = 1 << base_shift, - base_mask = base_size - 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_)) {} -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_conv_adaptor_vcgen.h b/core/src/fxge/agg/agg23/agg_conv_adaptor_vcgen.h deleted file mode 100644 index 0d8d6ff99e..0000000000 --- a/core/src/fxge/agg/agg23/agg_conv_adaptor_vcgen.h +++ /dev/null @@ -1,138 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -#ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED -#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED -#include "agg_basics.h" -namespace agg -{ -struct null_markers { - void remove_all() {} - void add_vertex(FX_FLOAT, FX_FLOAT, unsigned) {} - void prepare_src() {} - void rewind(unsigned) {} - unsigned vertex(FX_FLOAT*, FX_FLOAT*) - { - return path_cmd_stop; - } -}; -template class conv_adaptor_vcgen -{ - enum status { - initial, - accumulate, - generate - }; -public: - conv_adaptor_vcgen(VertexSource& source) : - m_source(&source), - m_status(initial) - {} - void set_source(VertexSource& source) - { - m_source = &source; - } - Generator& generator() - { - return m_generator; - } - const Generator& generator() const - { - return m_generator; - } - Markers& markers() - { - return m_markers; - } - const Markers& markers() const - { - return m_markers; - } - void rewind(unsigned path_id) - { - m_source->rewind(path_id); - m_status = initial; - } - unsigned vertex(FX_FLOAT* x, FX_FLOAT* y); -private: - conv_adaptor_vcgen(const conv_adaptor_vcgen&); - const conv_adaptor_vcgen& - operator = (const conv_adaptor_vcgen&); - VertexSource* m_source; - Generator m_generator; - Markers m_markers; - status m_status; - unsigned m_last_cmd; - FX_FLOAT m_start_x; - FX_FLOAT m_start_y; -}; -template -unsigned conv_adaptor_vcgen::vertex(FX_FLOAT* x, FX_FLOAT* y) -{ - unsigned cmd = path_cmd_stop; - bool done = false; - while(!done) { - switch(m_status) { - case initial: - m_markers.remove_all(); - m_last_cmd = m_source->vertex(&m_start_x, &m_start_y); - m_status = accumulate; - case accumulate: - if(is_stop(m_last_cmd)) { - return path_cmd_stop; - } - m_generator.remove_all(); - m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to); - m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to); - for(;;) { - cmd = m_source->vertex(x, y); - if(is_vertex(cmd)) { - m_last_cmd = cmd; - if(is_move_to(cmd)) { - m_start_x = *x; - m_start_y = *y; - break; - } - m_generator.add_vertex(*x, *y, cmd); - m_markers.add_vertex(*x, *y, path_cmd_line_to); - } else { - if(is_stop(cmd)) { - m_last_cmd = path_cmd_stop; - break; - } - if(is_end_poly(cmd)) { - m_generator.add_vertex(*x, *y, cmd); - break; - } - } - } - m_generator.rewind(0); - m_status = generate; - case generate: - cmd = m_generator.vertex(x, y); - if(is_stop(cmd)) { - m_status = accumulate; - break; - } - done = true; - break; - } - } - return cmd; -} -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_conv_dash.h b/core/src/fxge/agg/agg23/agg_conv_dash.h deleted file mode 100644 index 63b2019dde..0000000000 --- a/core/src/fxge/agg/agg23/agg_conv_dash.h +++ /dev/null @@ -1,61 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// conv_dash -// -//---------------------------------------------------------------------------- -#ifndef AGG_CONV_DASH_INCLUDED -#define AGG_CONV_DASH_INCLUDED -#include "agg_basics.h" -#include "agg_vcgen_dash.h" -#include "agg_conv_adaptor_vcgen.h" -namespace agg -{ -template -struct conv_dash : public conv_adaptor_vcgen { - typedef Markers marker_type; - typedef conv_adaptor_vcgen base_type; - conv_dash(VertexSource& vs) : - conv_adaptor_vcgen(vs) - { - } - void remove_all_dashes() - { - base_type::generator().remove_all_dashes(); - } - void add_dash(FX_FLOAT dash_len, FX_FLOAT gap_len) - { - base_type::generator().add_dash(dash_len, gap_len); - } - void dash_start(FX_FLOAT ds) - { - base_type::generator().dash_start(ds); - } - void shorten(FX_FLOAT s) - { - base_type::generator().shorten(s); - } - double shorten() const - { - return base_type::generator().shorten(); - } -private: - conv_dash(const conv_dash&); - const conv_dash& - operator = (const conv_dash&); -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_conv_stroke.h b/core/src/fxge/agg/agg23/agg_conv_stroke.h deleted file mode 100644 index 5a36bd73bb..0000000000 --- a/core/src/fxge/agg/agg23/agg_conv_stroke.h +++ /dev/null @@ -1,110 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// conv_stroke -// -//---------------------------------------------------------------------------- -#ifndef AGG_CONV_STROKE_INCLUDED -#define AGG_CONV_STROKE_INCLUDED -#include "agg_basics.h" -#include "agg_vcgen_stroke.h" -#include "agg_conv_adaptor_vcgen.h" -namespace agg -{ -template -struct conv_stroke : - public conv_adaptor_vcgen { - typedef Markers marker_type; - typedef conv_adaptor_vcgen base_type; - conv_stroke(VertexSource& vs) : - conv_adaptor_vcgen(vs) - { - } - 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(); - } - inner_join_e inner_join() const - { - return base_type::generator().inner_join(); - } - void width(FX_FLOAT w) - { - base_type::generator().width(w); - } - void miter_limit(FX_FLOAT ml) - { - base_type::generator().miter_limit(ml); - } - void miter_limit_theta(FX_FLOAT t) - { - base_type::generator().miter_limit_theta(t); - } - void inner_miter_limit(FX_FLOAT ml) - { - base_type::generator().inner_miter_limit(ml); - } - void approximation_scale(FX_FLOAT as) - { - base_type::generator().approximation_scale(as); - } - FX_FLOAT width() const - { - return base_type::generator().width(); - } - FX_FLOAT miter_limit() const - { - return base_type::generator().miter_limit(); - } - FX_FLOAT inner_miter_limit() const - { - return base_type::generator().inner_miter_limit(); - } - FX_FLOAT approximation_scale() const - { - return base_type::generator().approximation_scale(); - } - void shorten(FX_FLOAT s) - { - base_type::generator().shorten(s); - } - FX_FLOAT shorten() const - { - return base_type::generator().shorten(); - } -private: - conv_stroke(const conv_stroke&); - const conv_stroke& - operator = (const conv_stroke&); -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_curves.h b/core/src/fxge/agg/agg23/agg_curves.h deleted file mode 100644 index 495f7a6a8f..0000000000 --- a/core/src/fxge/agg/agg23/agg_curves.h +++ /dev/null @@ -1,188 +0,0 @@ - -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.3 -// 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. -// 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_CURVES_INCLUDED -#define AGG_CURVES_INCLUDED -#include "agg_array.h" -namespace agg -{ -struct curve4_points { - FX_FLOAT cp[8]; - curve4_points() {} - curve4_points(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT 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(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT 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; - } - FX_FLOAT operator [] (unsigned i) const - { - return cp[i]; - } - FX_FLOAT& operator [] (unsigned i) - { - return cp[i]; - } -}; -class curve4_div -{ -public: - curve4_div() : - m_count(0) - {} - curve4_div(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT y4) : - m_count(0) - { - init(x1, y1, x2, y2, x3, y3, x4, y4); - } - curve4_div(const curve4_points& cp) : - 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(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT 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 rewind(unsigned) - { - m_count = 0; - } - unsigned vertex(FX_FLOAT* x, FX_FLOAT* y) - { - if(m_count >= m_points.size()) { - return path_cmd_stop; - } - const point_type& p = m_points[m_count++]; - *x = p.x; - *y = p.y; - return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; - } - unsigned vertex_flag(FX_FLOAT* x, FX_FLOAT* y, int& flag) - { - if(m_count >= m_points.size()) { - return path_cmd_stop; - } - const point_type& p = m_points[m_count++]; - *x = p.x; - *y = p.y; - flag = p.flag; - return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; - } - int count() - { - return m_points.size(); - } -private: - void bezier(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT y4); - void recursive_bezier(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT y4, - unsigned level); - FX_FLOAT m_distance_tolerance_square; - FX_FLOAT m_distance_tolerance_manhattan; - unsigned m_count; - pod_deque m_points; -}; -class curve4 -{ -public: - curve4() {} - curve4(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT y4) - { - init(x1, y1, x2, y2, x3, y3, x4, y4); - } - curve4(const curve4_points& cp) - { - init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); - } - void reset() - { - m_curve_div.reset(); - } - void init(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT y4) - { - 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 rewind(unsigned path_id) - { - m_curve_div.rewind(path_id); - } - unsigned vertex(FX_FLOAT* x, FX_FLOAT* y) - { - return m_curve_div.vertex(x, y); - } - unsigned vertex_curve_flag(FX_FLOAT* x, FX_FLOAT* y, int& flag) - { - return m_curve_div.vertex_flag(x, y, flag); - } - int count() - { - return m_curve_div.count(); - } -private: - curve4_div m_curve_div; -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_math.h b/core/src/fxge/agg/agg23/agg_math.h deleted file mode 100644 index 31e0daf3bb..0000000000 --- a/core/src/fxge/agg/agg23/agg_math.h +++ /dev/null @@ -1,63 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// 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 -#include "agg_basics.h" -namespace agg -{ -const FX_FLOAT intersection_epsilon = 1.0e-30f; -AGG_INLINE FX_FLOAT calc_point_location(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x, FX_FLOAT y) -{ - return FXSYS_Mul(x - x2, y2 - y1) - FXSYS_Mul(y - y2, x2 - x1); -} -AGG_INLINE FX_FLOAT calc_distance(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) -{ - FX_FLOAT dx = x2 - x1; - FX_FLOAT dy = y2 - y1; - return FXSYS_sqrt2(dx, dy); -} -AGG_INLINE FX_FLOAT calc_line_point_distance(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x, FX_FLOAT y) -{ - FX_FLOAT dx = x2 - x1; - FX_FLOAT dy = y2 - y1; - FX_FLOAT d = FXSYS_sqrt2(dx, dy); - if(d < intersection_epsilon) { - return calc_distance(x1, y1, x, y); - } - return FXSYS_MulDiv(x - x2, dy, d) - FXSYS_MulDiv(y - y2, dx, d); -} -AGG_INLINE bool calc_intersection(FX_FLOAT ax, FX_FLOAT ay, FX_FLOAT bx, FX_FLOAT by, - FX_FLOAT cx, FX_FLOAT cy, FX_FLOAT dx, FX_FLOAT dy, - FX_FLOAT* x, FX_FLOAT* y) -{ - FX_FLOAT num = FXSYS_Mul(ay - cy, dx - cx) - FXSYS_Mul(ax - cx, dy - cy); - FX_FLOAT den = FXSYS_Mul(bx - ax, dy - cy) - FXSYS_Mul(by - ay, dx - cx); - if (FXSYS_fabs(den) < intersection_epsilon) { - return false; - } - *x = ax + FXSYS_MulDiv(bx - ax, num, den); - *y = ay + FXSYS_MulDiv(by - ay, num, den); - return true; -} -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_math_stroke.h b/core/src/fxge/agg/agg23/agg_math_stroke.h deleted file mode 100644 index 620d675312..0000000000 --- a/core/src/fxge/agg/agg23/agg_math_stroke.h +++ /dev/null @@ -1,272 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Stroke math -// -//---------------------------------------------------------------------------- -#ifndef AGG_STROKE_MATH_INCLUDED -#define AGG_STROKE_MATH_INCLUDED -#include "agg_math.h" -#include "agg_vertex_sequence.h" -namespace agg -{ -enum line_cap_e { - butt_cap, - square_cap, - round_cap -}; -enum line_join_e { - miter_join = 0, - miter_join_revert = 1, - miter_join_round = 4, - round_join = 2, - bevel_join = 3 -}; -enum inner_join_e { - inner_bevel, - inner_miter, - inner_jag, - inner_round -}; -const FX_FLOAT stroke_theta = 1.0f / 1000.0f; -template -void stroke_calc_arc(VertexConsumer& out_vertices, - FX_FLOAT x, FX_FLOAT y, - FX_FLOAT dx1, FX_FLOAT dy1, - FX_FLOAT dx2, FX_FLOAT dy2, - FX_FLOAT width, - FX_FLOAT approximation_scale) -{ - typedef typename VertexConsumer::value_type coord_type; - FX_FLOAT a1 = FXSYS_atan2(dy1, dx1); - FX_FLOAT a2 = FXSYS_atan2(dy2, dx2); - FX_FLOAT da = a1 - a2; - bool ccw = da > 0 && da < FX_PI; - if(width < 0) { - width = -width; - } - da = FXSYS_acos(FXSYS_Div(width, width + FXSYS_Div(1.0f / 8, approximation_scale))) * 2; - out_vertices.add(coord_type(x + dx1, y + dy1)); - if(!ccw) { - if(a1 > a2) { - a2 += 2 * FX_PI; - } - a2 -= da / 4; - a1 += da; - while(a1 < a2) { - out_vertices.add(coord_type(x + FXSYS_Mul(width, FXSYS_cos(a1)), - y + FXSYS_Mul(width, FXSYS_sin(a1)))); - a1 += da; - } - } else { - if(a1 < a2) { - a2 -= 2 * FX_PI; - } - a2 += da / 4; - a1 -= da; - while(a1 > a2) { - out_vertices.add(coord_type(x + FXSYS_Mul(width, FXSYS_cos(a1)), - y + FXSYS_Mul(width, FXSYS_sin(a1)))); - a1 -= da; - } - } - out_vertices.add(coord_type(x + dx2, y + dy2)); -} -template -void stroke_calc_miter(VertexConsumer& out_vertices, - const vertex_dist& v0, - const vertex_dist& v1, - const vertex_dist& v2, - FX_FLOAT dx1, FX_FLOAT dy1, - FX_FLOAT dx2, FX_FLOAT dy2, - FX_FLOAT width, - line_join_e line_join, - FX_FLOAT miter_limit, - FX_FLOAT approximation_scale) -{ - typedef typename VertexConsumer::value_type coord_type; - FX_FLOAT xi = v1.x; - FX_FLOAT yi = v1.y; - bool miter_limit_exceeded = true; - 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)) { - FX_FLOAT d1 = calc_distance(v1.x, v1.y, xi, yi); - FX_FLOAT lim = FXSYS_Mul(width, miter_limit); - if(d1 <= lim) { - out_vertices.add(coord_type(xi, yi)); - miter_limit_exceeded = false; - } - } else { - FX_FLOAT x2 = v1.x + dx1; - FX_FLOAT y2 = v1.y - dy1; - if((FXSYS_Mul(x2 - v0.x, dy1) - FXSYS_Mul(v0.y - y2, dx1) < 0) != - (FXSYS_Mul(x2 - v2.x, dy1) - FXSYS_Mul(v2.y - y2, dx1) < 0)) { - out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); - miter_limit_exceeded = false; - } - } - if(miter_limit_exceeded) { - switch(line_join) { - case miter_join_revert: - 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: - stroke_calc_arc(out_vertices, - v1.x, v1.y, dx1, -dy1, dx2, -dy2, - width, approximation_scale); - break; - default: - out_vertices.add(coord_type(v1.x + dx1 + FXSYS_Mul(dy1, miter_limit), - v1.y - dy1 + FXSYS_Mul(dx1, miter_limit))); - out_vertices.add(coord_type(v1.x + dx2 - FXSYS_Mul(dy2, miter_limit), - v1.y - dy2 - FXSYS_Mul(dx2, miter_limit))); - break; - } - } -} -template -void stroke_calc_cap(VertexConsumer& out_vertices, - const vertex_dist& v0, - const vertex_dist& v1, - FX_FLOAT len, - line_cap_e line_cap, - FX_FLOAT width, - FX_FLOAT approximation_scale) -{ - typedef typename VertexConsumer::value_type coord_type; - out_vertices.remove_all(); - FX_FLOAT dx1 = FXSYS_Div(v1.y - v0.y, len); - FX_FLOAT dy1 = FXSYS_Div(v1.x - v0.x, len); - FX_FLOAT dx2 = 0; - FX_FLOAT dy2 = 0; - dx1 = FXSYS_Mul(dx1, width); - dy1 = FXSYS_Mul(dy1, width); - if(line_cap != round_cap) { - if(line_cap == square_cap) { - dx2 = dy1; - dy2 = dx1; - } - 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 { - FX_FLOAT a1 = FXSYS_atan2(dy1, -dx1); - FX_FLOAT a2 = a1 + FX_PI; - FX_FLOAT da = FXSYS_acos(FXSYS_Div(width, width + - FXSYS_Div(1.0f / 8, approximation_scale))) * 2; - out_vertices.add(coord_type(v0.x - dx1, v0.y + dy1)); - a1 += da; - a2 -= da / 4; - while(a1 < a2) { - out_vertices.add(coord_type(v0.x + FXSYS_Mul(width, FXSYS_cos(a1)), - v0.y + FXSYS_Mul(width, FXSYS_sin(a1)))); - a1 += da; - } - out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1)); - } -} -template -void stroke_calc_join(VertexConsumer& out_vertices, - const vertex_dist& v0, - const vertex_dist& v1, - const vertex_dist& v2, - FX_FLOAT len1, - FX_FLOAT len2, - FX_FLOAT width, - line_join_e line_join, - inner_join_e inner_join, - FX_FLOAT miter_limit, - FX_FLOAT inner_miter_limit, - FX_FLOAT approximation_scale) -{ - typedef typename VertexConsumer::value_type coord_type; - FX_FLOAT dx1, dy1, dx2, dy2; - dx1 = FXSYS_MulDiv(width, v1.y - v0.y, len1); - dy1 = FXSYS_MulDiv(width, v1.x - v0.x, len1); - dx2 = FXSYS_MulDiv(width, v2.y - v1.y, len2); - dy2 = FXSYS_MulDiv(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) { - switch(inner_join) { - default: - 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: - stroke_calc_miter(out_vertices, - v0, v1, v2, dx1, dy1, dx2, dy2, - width, - miter_join_revert, - inner_miter_limit, - 1.0f); - break; - case inner_jag: - case inner_round: { - FX_FLOAT d = (dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2); - if(d < len1 * len1 && d < len2 * len2) { - stroke_calc_miter(out_vertices, - v0, v1, v2, dx1, dy1, dx2, dy2, - width, - miter_join_revert, - inner_miter_limit, - 1.0f); - } else { - if(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 )); - stroke_calc_arc(out_vertices, - v1.x, v1.y, dx2, -dy2, dx1, -dy1, - width, approximation_scale); - out_vertices.add(coord_type(v1.x, v1.y )); - out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); - } - } - } - break; - } - } else { - switch(line_join) { - case miter_join: - case miter_join_revert: - case miter_join_round: - stroke_calc_miter(out_vertices, - v0, v1, v2, dx1, dy1, dx2, dy2, - width, - line_join, - miter_limit, - approximation_scale); - break; - case round_join: - stroke_calc_arc(out_vertices, - v1.x, v1.y, dx1, -dy1, dx2, -dy2, - width, approximation_scale); - break; - default: - out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); - out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); - break; - } - } -} -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_path_storage.h b/core/src/fxge/agg/agg23/agg_path_storage.h deleted file mode 100644 index dc13851d09..0000000000 --- a/core/src/fxge/agg/agg23/agg_path_storage.h +++ /dev/null @@ -1,172 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -#ifndef AGG_PATH_STORAGE_INCLUDED -#define AGG_PATH_STORAGE_INCLUDED -#include "agg_basics.h" -namespace agg -{ -class path_storage -{ - enum block_scale_e { - block_shift = 8, - block_size = 1 << block_shift, - block_mask = block_size - 1, - block_pool = 256 - }; -public: - class vertex_source - { - public: - vertex_source() {} - vertex_source(const path_storage& p) : m_path(&p), m_vertex_idx(0) {} - void rewind(unsigned path_id) - { - m_vertex_idx = path_id; - } - unsigned vertex(FX_FLOAT* x, FX_FLOAT* y) - { - return (m_vertex_idx < m_path->total_vertices()) ? - m_path->vertex(m_vertex_idx++, x, y) : - path_cmd_stop; - } - private: - const path_storage* m_path; - unsigned m_vertex_idx; - }; - ~path_storage(); - path_storage(); - unsigned last_vertex(FX_FLOAT* x, FX_FLOAT* y) const; - unsigned prev_vertex(FX_FLOAT* x, FX_FLOAT* y) const; - void move_to(FX_FLOAT x, FX_FLOAT y); - void line_to(FX_FLOAT x, FX_FLOAT y); - void curve4(FX_FLOAT x_ctrl1, FX_FLOAT y_ctrl1, - FX_FLOAT x_ctrl2, FX_FLOAT y_ctrl2, - FX_FLOAT x_to, FX_FLOAT y_to); - template - void add_path(VertexSource& vs, - unsigned path_id = 0, - bool solid_path = true) - { - FX_FLOAT 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); - } - } - template - void add_path_curve(VertexSource& vs, - unsigned path_id = 0, - bool solid_path = true) - { - FX_FLOAT x, y; - unsigned cmd; - int flag; - vs.rewind(path_id); - while(!is_stop(cmd = vs.vertex_curve_flag(&x, &y, flag))) { - if(is_move_to(cmd) && solid_path && m_total_vertices) { - cmd = path_cmd_line_to | flag; - } - add_vertex(x, y, cmd | flag); - } - } - unsigned total_vertices() const - { - return m_total_vertices; - } - unsigned vertex(unsigned idx, FX_FLOAT* x, FX_FLOAT* y) const - { - unsigned nb = idx >> block_shift; - const FX_FLOAT* 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]; - } - unsigned getflag(unsigned idx) const - { - return m_cmd_blocks[idx >> block_shift][idx & block_mask] & path_flags_jr; - } - void rewind(unsigned path_id); - unsigned vertex(FX_FLOAT* x, FX_FLOAT* y); - void add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd); - void end_poly(); -private: - void allocate_block(unsigned nb); - unsigned char* storage_ptrs(FX_FLOAT** xy_ptr); -private: - unsigned m_total_vertices; - unsigned m_total_blocks; - unsigned m_max_blocks; - FX_FLOAT** m_coord_blocks; - unsigned char** m_cmd_blocks; - unsigned m_iterator; -}; -inline unsigned path_storage::vertex(FX_FLOAT* x, FX_FLOAT* y) -{ - if(m_iterator >= m_total_vertices) { - return path_cmd_stop; - } - return vertex(m_iterator++, x, y); -} -inline unsigned path_storage::prev_vertex(FX_FLOAT* x, FX_FLOAT* y) const -{ - if(m_total_vertices > 1) { - return vertex(m_total_vertices - 2, x, y); - } - return path_cmd_stop; -} -inline unsigned path_storage::last_vertex(FX_FLOAT* x, FX_FLOAT* y) const -{ - if(m_total_vertices) { - return vertex(m_total_vertices - 1, x, y); - } - return path_cmd_stop; -} -inline unsigned char* path_storage::storage_ptrs(FX_FLOAT** 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); -} -inline void path_storage::add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd) -{ - FX_FLOAT* 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(FX_FLOAT x, FX_FLOAT y) -{ - add_vertex(x, y, path_cmd_move_to); -} -inline void path_storage::line_to(FX_FLOAT x, FX_FLOAT y) -{ - add_vertex(x, y, path_cmd_line_to); -} -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_pixfmt_gray.h b/core/src/fxge/agg/agg23/agg_pixfmt_gray.h deleted file mode 100644 index 5a80935479..0000000000 --- a/core/src/fxge/agg/agg23/agg_pixfmt_gray.h +++ /dev/null @@ -1,177 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// 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 "agg_basics.h" -#include "agg_color_gray.h" -#include "agg_rendering_buffer.h" -namespace agg -{ -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); - } -}; -template -class pixel_formats_gray -{ -public: - typedef rendering_buffer::row_data row_data; - typedef rendering_buffer::span_data span_data; - typedef typename Blender::color_type 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, - base_size = color_type::base_size, - base_mask = color_type::base_mask - }; -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: - pixel_formats_gray(rendering_buffer& rb) : - m_rbuf(&rb) - {} - AGG_INLINE unsigned width() const - { - return m_rbuf->width(); - } - AGG_INLINE unsigned height() const - { - return m_rbuf->height(); - } - AGG_INLINE color_type pixel(int x, int y) const - { - value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset; - return color_type(*p); - } - row_data row(int x, int y) const - { - return row_data(x, - width() - 1, - m_rbuf->row(y) + - x * Step * sizeof(value_type) + - Offset * sizeof(value_type)); - } - span_data span(int x, int y, unsigned len) - { - return span_data(x, len, - m_rbuf->row(y) + - x * Step * sizeof(value_type) + - Offset * sizeof(value_type)); - } - AGG_INLINE void copy_pixel(int x, int y, const color_type& c) - { - *((value_type*)m_rbuf->row(y) + 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(y) + 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(y) + x * Step + Offset; - do { - *p = c.v; - p += Step; - } 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(y) + 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_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(y) + 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); - } - } -private: - rendering_buffer* m_rbuf; -}; -typedef blender_gray blender_gray8; -typedef pixel_formats_gray pixfmt_gray8; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_rasterizer_scanline_aa.h b/core/src/fxge/agg/agg23/agg_rasterizer_scanline_aa.h deleted file mode 100644 index e06322c24d..0000000000 --- a/core/src/fxge/agg/agg23/agg_rasterizer_scanline_aa.h +++ /dev/null @@ -1,472 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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_SCANLINE_AA_INCLUDED -#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED -#include "../../../../include/fxge/fx_ge.h" -#include "agg_basics.h" -#include "agg_math.h" -#include "agg_array.h" -#include "agg_clip_liang_barsky.h" -#include "agg_render_scanlines.h" -namespace agg -{ -enum poly_base_scale_e { - poly_base_shift = 8, - poly_base_size = 1 << poly_base_shift, - poly_base_mask = poly_base_size - 1 -}; -inline int poly_coord(FX_FLOAT c) -{ - return int(c * poly_base_size); -} -struct cell_aa { - 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); -}; -class outline_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: - ~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; - } - 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_aa* 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: - 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 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(); -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; - pod_array m_sorted_cells; - pod_array m_sorted_y; - 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; -}; -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; -}; -enum filling_rule_e { - fill_non_zero, - fill_even_odd -}; -class rasterizer_scanline_aa -{ - enum status { - status_initial, - status_line_to, - status_closed - }; -public: - enum aa_scale_e { - aa_num = 1 << 8, - aa_mask = aa_num - 1, - aa_2num = aa_num * 2, - aa_2mask = aa_2num - 1 - }; - rasterizer_scanline_aa() : - m_filling_rule(fill_non_zero), - m_clipped_start_x(0), - m_clipped_start_y(0), - m_status(status_initial), - m_clipping(false) - { - } - ~rasterizer_scanline_aa() {} - void filling_rule(filling_rule_e filling_rule) - { - m_filling_rule = filling_rule; - } - 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(); - } - void reset() - { - m_outline.reset(); - m_status = status_initial; - } - void clip_box(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) - { - m_clip_box = rect(poly_coord(x1), poly_coord(y1), - poly_coord(x2), poly_coord(y2)); - m_clip_box.normalize(); - m_clipping = true; - } - void add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd) - { - 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)); - } - } - } - } - void 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); - } - } - void line_to(int x, int y) - { - if(m_clipping) { - clip_segment(x, y); - } else { - line_to_no_clip(x, y); - } - } - void close_polygon() - { - if (m_status != status_line_to) { - return; - } - if(m_clipping) { - clip_segment(m_start_x, m_start_y); - } - close_polygon_no_clip(); - } - AGG_INLINE unsigned calculate_alpha(int area, bool no_smooth) const - { - int cover = area >> (poly_base_shift * 2 + 1 - 8); - if(cover < 0) { - cover = -cover; - } - if(m_filling_rule == fill_even_odd) { - cover &= aa_2mask; - if(cover > aa_num) { - cover = aa_2num - cover; - } - } - if (no_smooth) { - cover = cover > aa_mask / 2 ? aa_mask : 0; - } - if(cover > aa_mask) { - cover = aa_mask; - } - return cover; - } - AGG_INLINE void sort() - { - m_outline.sort_cells(); - } - AGG_INLINE bool rewind_scanlines() - { - close_polygon(); - m_outline.sort_cells(); - if(m_outline.total_cells() == 0) { - return false; - } - m_cur_y = m_outline.min_y(); - return true; - } - AGG_INLINE bool navigate_scanline(int y) - { - 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_cur_y = y; - return true; - } - template bool sweep_scanline(Scanline& sl, bool no_smooth) - { - for(;;) { - if(m_cur_y > m_outline.max_y()) { - return false; - } - sl.reset_spans(); - unsigned num_cells = m_outline.scanline_num_cells(m_cur_y); - const cell_aa* const* cells = m_outline.scanline_cells(m_cur_y); - int cover = 0; - while(num_cells) { - const cell_aa* cur_cell = *cells; - int x = cur_cell->x; - int area = cur_cell->area; - unsigned alpha; - cover += cur_cell->cover; - while(--num_cells) { - cur_cell = *++cells; - if(cur_cell->x != x) { - break; - } - area += cur_cell->area; - cover += cur_cell->cover; - } - if(area) { - alpha = calculate_alpha((cover << (poly_base_shift + 1)) - area, no_smooth); - if(alpha) { - sl.add_cell(x, alpha); - } - x++; - } - if(num_cells && cur_cell->x > x) { - alpha = calculate_alpha(cover << (poly_base_shift + 1), no_smooth); - if(alpha) { - sl.add_span(x, cur_cell->x - x, alpha); - } - } - } - if(sl.num_spans()) { - break; - } - ++m_cur_y; - } - sl.finalize(m_cur_y); - ++m_cur_y; - return true; - } - template - void add_path(VertexSource& vs, unsigned path_id = 0) - { - FX_FLOAT x; - FX_FLOAT y; - unsigned cmd; - vs.rewind(path_id); - while(!is_stop(cmd = vs.vertex(&x, &y))) { - add_vertex(x, y, cmd); - } - } - template - void add_path_transformed(VertexSource& vs, const CFX_AffineMatrix* pMatrix, unsigned path_id = 0) - { - FX_FLOAT x; - FX_FLOAT y; - unsigned cmd; - vs.rewind(path_id); - while(!is_stop(cmd = vs.vertex(&x, &y))) { - if (pMatrix) { - pMatrix->Transform(x, y); - } - add_vertex(x, y, cmd); - } - } -private: - 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) - { - if(m_status == status_line_to) { - close_polygon_no_clip(); - } - m_outline.move_to(x * 1, y); - m_clipped_start_x = x; - m_clipped_start_y = y; - m_status = status_line_to; - } - void line_to_no_clip(int x, int y) - { - if(m_status != status_initial) { - m_outline.line_to(x * 1, y); - m_status = status_line_to; - } - } - void close_polygon_no_clip() - { - if(m_status == status_line_to) { - m_outline.line_to(m_clipped_start_x * 1, m_clipped_start_y); - m_status = status_closed; - } - } - void clip_segment(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; - } -private: - outline_aa m_outline; - 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; - unsigned m_status; - rect m_clip_box; - bool m_clipping; - int m_cur_y; -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_render_scanlines.h b/core/src/fxge/agg/agg23/agg_render_scanlines.h deleted file mode 100644 index 0dfd6d259f..0000000000 --- a/core/src/fxge/agg/agg23/agg_render_scanlines.h +++ /dev/null @@ -1,50 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// 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 -{ -template -void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren, bool no_smooth) -{ - 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, no_smooth)) { - ren.render(sl); - } - } -} -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); - } -} -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_renderer_base.h b/core/src/fxge/agg/agg23/agg_renderer_base.h deleted file mode 100644 index bd1b203b9a..0000000000 --- a/core/src/fxge/agg/agg23/agg_renderer_base.h +++ /dev/null @@ -1,163 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// class renderer_base -// -//---------------------------------------------------------------------------- -#ifndef AGG_RENDERER_BASE_INCLUDED -#define AGG_RENDERER_BASE_INCLUDED -#include "agg_basics.h" -#include "agg_rendering_buffer.h" -namespace agg -{ -template class renderer_base -{ -public: - typedef PixelFormat pixfmt_type; - typedef typename pixfmt_type::color_type color_type; - typedef typename pixfmt_type::row_data row_data; - typedef typename pixfmt_type::span_data span_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(0, 0, ren.width() - 1, ren.height() - 1); - } - const pixfmt_type& ren() const - { - return *m_ren; - } - pixfmt_type& ren() - { - return *m_ren; - } - unsigned width() const - { - return m_ren->width(); - } - unsigned height() const - { - return m_ren->height(); - } - 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& 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 blend_hline(int x1, int y, int x2, - const color_type& c, cover_type cover) - { - if(x1 > x2) { - int t = x2; - x2 = x1; - x1 = t; - } - if(y > ymax()) { - return; - } - if(y < ymin()) { - return; - } - if(x1 > xmax()) { - return; - } - if(x2 < xmin()) { - return; - } - if(x1 < xmin()) { - x1 = xmin(); - } - if(x2 > xmax()) { - x2 = xmax(); - } - m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover); - } - void blend_solid_hspan(int x, int y, int len, - const color_type& c, - const cover_type* covers) - { - if(y > ymax()) { - return; - } - if(y < ymin()) { - return; - } - if(x < xmin()) { - len -= xmin() - x; - if(len <= 0) { - return; - } - covers += xmin() - x; - x = xmin(); - } - if(x + len > xmax()) { - len = xmax() - x + 1; - if(len <= 0) { - return; - } - } - m_ren->blend_solid_hspan(x, y, len, c, covers); - } -private: - pixfmt_type* m_ren; - rect m_clip_box; -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_renderer_scanline.h b/core/src/fxge/agg/agg23/agg_renderer_scanline.h deleted file mode 100644 index 62d104f7f2..0000000000 --- a/core/src/fxge/agg/agg23/agg_renderer_scanline.h +++ /dev/null @@ -1,93 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -#ifndef AGG_RENDERER_SCANLINE_INCLUDED -#define AGG_RENDERER_SCANLINE_INCLUDED -#include "agg_basics.h" -#include "agg_renderer_base.h" -#include "agg_render_scanlines.h" -namespace agg -{ -template class renderer_scanline_aa -{ -public: - typedef BaseRenderer base_ren_type; - typedef SpanGenerator span_gen_type; - renderer_scanline_aa() : m_ren(0), m_span_gen(0) {} - renderer_scanline_aa(base_ren_type& ren, span_gen_type& span_gen) : - m_ren(&ren), - m_span_gen(&span_gen) - {} - void attach(base_ren_type& ren, span_gen_type& span_gen) - { - m_ren = &ren; - m_span_gen = &span_gen; - } - 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 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(); - for(;;) { - 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); - } - } - if(--num_spans == 0) { - break; - } - ++span; - } - } - } while(m_ren->next_clip_box()); - } -private: - base_ren_type* m_ren; - SpanGenerator* m_span_gen; -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_rendering_buffer.h b/core/src/fxge/agg/agg23/agg_rendering_buffer.h deleted file mode 100644 index 9c1c0c6899..0000000000 --- a/core/src/fxge/agg/agg23/agg_rendering_buffer.h +++ /dev/null @@ -1,145 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// class rendering_buffer -// -//---------------------------------------------------------------------------- -#ifndef AGG_RENDERING_BUFFER_INCLUDED -#define AGG_RENDERING_BUFFER_INCLUDED -#include "agg_basics.h" -namespace agg -{ -class rendering_buffer -{ -public: - struct row_data { - int x1, x2; - const int8u* ptr; - row_data() {} - row_data(int x1_, int x2_, const int8u* ptr_) : - x1(x1_), x2(x2_), ptr(ptr_) {} - }; - struct span_data { - int x; - unsigned len; - int8u* ptr; - span_data() {} - span_data(int) : x(0), len(0), ptr(0) {} - span_data(int x_, unsigned len_, int8u* ptr_) : - x(x_), len(len_), ptr(ptr_) {} - }; - ~rendering_buffer() - { - FX_Free(m_rows); - } - rendering_buffer() : - m_buf(0), - m_rows(0), - m_width(0), - m_height(0), - m_stride(0), - m_max_height(0) - { - } - rendering_buffer(int8u* buf, unsigned width, unsigned height, int stride) : - m_buf(0), - m_rows(0), - m_width(0), - m_height(0), - m_stride(0), - m_max_height(0) - { - attach(buf, width, height, stride); - } - void attach(int8u* buf, unsigned width, unsigned height, int stride) - { - m_buf = buf; - m_width = width; - m_height = height; - m_stride = stride; - if(height > m_max_height) { - FX_Free(m_rows); - m_rows = FX_Alloc(int8u*, m_max_height = height); - } - int8u* row_ptr = m_buf; - if(stride < 0) { - row_ptr = m_buf - int(height - 1) * stride; - } - int8u** rows = m_rows; - while(height--) { - *rows++ = row_ptr; - row_ptr += stride; - } - } - int8u* buf() - { - return m_buf; - } - const int8u* 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); - } - int8u* row(unsigned y) - { - return m_rows[y]; - } - const int8u* row(unsigned y) const - { - return m_rows[y]; - } - int8u* next_row(void* p) - { - return (int8u*)p + m_stride; - } - const int8u* next_row(const void* p) const - { - return (int8u*)p + m_stride; - } - int8u const* const* rows() const - { - return m_rows; - } -private: - rendering_buffer(const rendering_buffer&); - const rendering_buffer& operator = (const rendering_buffer&); -private: - int8u* m_buf; - int8u** m_rows; - unsigned m_width; - unsigned m_height; - int m_stride; - unsigned m_max_height; -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_scanline_u.h b/core/src/fxge/agg/agg23/agg_scanline_u.h deleted file mode 100644 index 2100115329..0000000000 --- a/core/src/fxge/agg/agg23/agg_scanline_u.h +++ /dev/null @@ -1,150 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// 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 "agg_array.h" -namespace agg -{ -template class scanline_u -{ -public: - typedef scanline_u self_type; - typedef CoverT cover_type; - typedef int16 coord_type; - struct span { - coord_type x; - coord_type len; - cover_type* covers; - }; - typedef span* iterator; - typedef const span* const_iterator; - ~scanline_u() - { - FX_Free(m_spans); - FX_Free(m_covers); - } - scanline_u() : - m_min_x(0), - m_max_len(0), - m_last_x(0x7FFFFFF0), - m_covers(0), - m_spans(0), - m_cur_span(0) - {} - void reset(int min_x, int max_x) - { - unsigned max_len = max_x - min_x + 2; - if(max_len > m_max_len) { - FX_Free(m_spans); - FX_Free(m_covers); - m_covers = FX_Alloc( cover_type , max_len); - m_spans = FX_Alloc( span , max_len); - m_max_len = max_len; - } - m_last_x = 0x7FFFFFF0; - m_min_x = min_x; - m_cur_span = m_spans; - } - 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 CoverT* covers) - { - x -= m_min_x; - FXSYS_memcpy(m_covers + x, covers, len * sizeof(CoverT)); - 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; - FXSYS_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; - } - 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; - } -private: - scanline_u(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; -}; -typedef scanline_u scanline_u8; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_shorten_path.h b/core/src/fxge/agg/agg23/agg_shorten_path.h deleted file mode 100644 index d7eb4be018..0000000000 --- a/core/src/fxge/agg/agg23/agg_shorten_path.h +++ /dev/null @@ -1,57 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -#ifndef AGG_SHORTEN_PATH_INCLUDED -#define AGG_SHORTEN_PATH_INCLUDED -#include "agg_basics.h" -#include "agg_vertex_sequence.h" -namespace agg -{ -template -void shorten_path(VertexSequence& vs, FX_FLOAT s, unsigned closed = 0) -{ - typedef typename VertexSequence::value_type vertex_type; - if(s > 0 && vs.size() > 1) { - FX_FLOAT d; - int n = int(vs.size() - 2); - while(n) { - d = vs[n].dist; - if(d > s) { - break; - } - vs.remove_last(); - s -= d; - --n; - } - if(vs.size() < 2) { - vs.remove_all(); - } else { - n = vs.size() - 1; - vertex_type& prev = vs[n - 1]; - vertex_type& last = vs[n]; - d = (prev.dist - s) / prev.dist; - FX_FLOAT x = prev.x + (last.x - prev.x) * d; - FX_FLOAT y = prev.y + (last.y - prev.y) * d; - last.x = x; - last.y = y; - if(!prev(last)) { - vs.remove_last(); - } - vs.close(closed != 0); - } - } -} -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_vcgen_dash.h b/core/src/fxge/agg/agg23/agg_vcgen_dash.h deleted file mode 100644 index 9c3aa630c2..0000000000 --- a/core/src/fxge/agg/agg23/agg_vcgen_dash.h +++ /dev/null @@ -1,75 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Line dash generator -// -//---------------------------------------------------------------------------- -#ifndef AGG_VCGEN_DASH_INCLUDED -#define AGG_VCGEN_DASH_INCLUDED -#include "agg_basics.h" -#include "agg_vertex_sequence.h" -namespace agg -{ -class vcgen_dash -{ - enum max_dashes_e { - max_dashes = 32 - }; - enum status_e { - initial, - ready, - polyline, - stop - }; -public: - typedef vertex_sequence vertex_storage; - vcgen_dash(); - void remove_all_dashes(); - void add_dash(FX_FLOAT dash_len, FX_FLOAT gap_len); - void dash_start(FX_FLOAT ds); - void shorten(FX_FLOAT s) - { - m_shorten = s; - } - double shorten() const - { - return m_shorten; - } - void remove_all(); - void add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd); - void rewind(unsigned path_id); - unsigned vertex(FX_FLOAT* x, FX_FLOAT* y); -private: - vcgen_dash(const vcgen_dash&); - const vcgen_dash& operator = (const vcgen_dash&); - void calc_dash_start(FX_FLOAT ds); - FX_FLOAT m_dashes[max_dashes]; - FX_FLOAT m_total_dash_len; - unsigned m_num_dashes; - FX_FLOAT m_dash_start; - FX_FLOAT m_shorten; - FX_FLOAT m_curr_dash_start; - unsigned m_curr_dash; - FX_FLOAT m_curr_rest; - const vertex_dist* m_v1; - const vertex_dist* m_v2; - vertex_storage m_src_vertices; - unsigned m_closed; - status_e m_status; - unsigned m_src_vertex; -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_vcgen_stroke.h b/core/src/fxge/agg/agg23/agg_vcgen_stroke.h deleted file mode 100644 index 84fadd6ed8..0000000000 --- a/core/src/fxge/agg/agg23/agg_vcgen_stroke.h +++ /dev/null @@ -1,120 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -#ifndef AGG_VCGEN_STROKE_INCLUDED -#define AGG_VCGEN_STROKE_INCLUDED -#include "agg_math_stroke.h" -namespace agg -{ -class vcgen_stroke -{ - enum status_e { - initial, - ready, - cap1, - cap2, - outline1, - close_first, - outline2, - out_vertices, - end_poly1, - end_poly2, - stop - }; -public: - typedef vertex_sequence vertex_storage; - typedef pod_deque 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_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(FX_FLOAT w) - { - m_width = w / 2; - } - void miter_limit(FX_FLOAT ml) - { - m_miter_limit = ml; - } - void miter_limit_theta(FX_FLOAT t); - void inner_miter_limit(FX_FLOAT ml) - { - m_inner_miter_limit = ml; - } - void approximation_scale(FX_FLOAT as) - { - m_approx_scale = as; - } - FX_FLOAT width() const - { - return m_width * 2; - } - FX_FLOAT miter_limit() const - { - return m_miter_limit; - } - FX_FLOAT inner_miter_limit() const - { - return m_inner_miter_limit; - } - FX_FLOAT approximation_scale() const - { - return m_approx_scale; - } - void remove_all(); - void add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd); - void rewind(unsigned path_id); - unsigned vertex(FX_FLOAT* x, FX_FLOAT* y); -private: - vcgen_stroke(const vcgen_stroke&); - const vcgen_stroke& operator = (const vcgen_stroke&); - vertex_storage m_src_vertices; - coord_storage m_out_vertices; - FX_FLOAT m_width; - FX_FLOAT m_miter_limit; - FX_FLOAT m_inner_miter_limit; - FX_FLOAT m_approx_scale; - line_cap_e m_line_cap; - line_join_e m_line_join; - inner_join_e m_inner_join; - unsigned m_closed; - status_e m_status; - status_e m_prev_status; - unsigned m_src_vertex; - unsigned m_out_vertex; -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/agg_vertex_sequence.h b/core/src/fxge/agg/agg23/agg_vertex_sequence.h deleted file mode 100644 index 6600bf2085..0000000000 --- a/core/src/fxge/agg/agg23/agg_vertex_sequence.h +++ /dev/null @@ -1,100 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// vertex_sequence container and vertex_dist struct -// -//---------------------------------------------------------------------------- -#ifndef AGG_VERTEX_SEQUENCE_INCLUDED -#define AGG_VERTEX_SEQUENCE_INCLUDED -#include "agg_basics.h" -#include "agg_array.h" -#include "agg_math.h" -namespace agg -{ -template -class vertex_sequence : public pod_deque -{ -public: - typedef pod_deque base_type; - void add(const T& val); - void modify_last(const T& val); - void close(bool remove_flag); -}; -template -void vertex_sequence::add(const T& val) -{ - if(base_type::size() > 1) { - if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) { - base_type::remove_last(); - } - } - base_type::add(val); -} -template -void vertex_sequence::modify_last(const T& val) -{ - base_type::remove_last(); - add(val); -} -template -void vertex_sequence::close(bool closed) -{ - while(base_type::size() > 1) { - if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) { - break; - } - T t = (*this)[base_type::size() - 1]; - base_type::remove_last(); - modify_last(t); - } - if(closed) { - while(base_type::size() > 1) { - if((*this)[base_type::size() - 1]((*this)[0])) { - break; - } - base_type::remove_last(); - } - } -} -const FX_FLOAT vertex_dist_epsilon = 1e-14f; -struct vertex_dist { - FX_FLOAT x; - FX_FLOAT y; - FX_FLOAT dist; - vertex_dist() {} - vertex_dist(FX_FLOAT x_, FX_FLOAT y_) : - x(x_), - y(y_), - dist(0) - { - } - bool operator () (const vertex_dist& val) - { - bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon; - return ret; - } -}; -struct vertex_dist_cmd : public vertex_dist { - unsigned cmd; - vertex_dist_cmd() {} - vertex_dist_cmd(FX_FLOAT x_, FX_FLOAT y_, unsigned cmd_) : - vertex_dist(x_, y_), - cmd(cmd_) - { - } -}; -} -#endif diff --git a/core/src/fxge/agg/agg23/fx_agg_curves.cpp b/core/src/fxge/agg/agg23/fx_agg_curves.cpp deleted file mode 100644 index 861320ee70..0000000000 --- a/core/src/fxge/agg/agg23/fx_agg_curves.cpp +++ /dev/null @@ -1,109 +0,0 @@ - -//---------------------------------------------------------------------------- -// XYQ: 2006-01-22 Copied from AGG project. -// TODO: This file uses intensive floating point operations, so it's NOT suitable -// for platforms like Symbian OS. We need to change to FIX format. -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -#include "../../../../include/fxcrt/fx_basic.h" -#include "agg_curves.h" -#include "agg_math.h" -namespace agg -{ -const FX_FLOAT curve_collinearity_epsilon = 1e-30f; -enum curve_recursion_limit_e { curve_recursion_limit = 16 }; -void curve4_div::init(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT y4) -{ - m_points.remove_all(); - m_distance_tolerance_square = 1.0f / 4; - m_distance_tolerance_manhattan = 1.0f * 4; - bezier(x1, y1, x2, y2, x3, y3, x4, y4); - m_count = 0; -} -void curve4_div::recursive_bezier(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT y4, - unsigned level) -{ - if(level > curve_recursion_limit) { - return; - } - FX_FLOAT x12 = (x1 + x2) / 2; - FX_FLOAT y12 = (y1 + y2) / 2; - FX_FLOAT x23 = (x2 + x3) / 2; - FX_FLOAT y23 = (y2 + y3) / 2; - FX_FLOAT x34 = (x3 + x4) / 2; - FX_FLOAT y34 = (y3 + y4) / 2; - FX_FLOAT x123 = (x12 + x23) / 2; - FX_FLOAT y123 = (y12 + y23) / 2; - FX_FLOAT x234 = (x23 + x34) / 2; - FX_FLOAT y234 = (y23 + y34) / 2; - FX_FLOAT x1234 = (x123 + x234) / 2; - FX_FLOAT y1234 = (y123 + y234) / 2; - FX_FLOAT dx = x4 - x1; - FX_FLOAT dy = y4 - y1; - FX_FLOAT d2 = FXSYS_fabs(FXSYS_Mul(x2 - x4, dy) - FXSYS_Mul(y2 - y4, dx)); - FX_FLOAT d3 = FXSYS_fabs(FXSYS_Mul(x3 - x4, dy) - FXSYS_Mul(y3 - y4, dx)); - switch((int(d2 > curve_collinearity_epsilon) << 1) + - int(d3 > curve_collinearity_epsilon)) { - case 0: - if(FXSYS_fabs(x1 + x3 - x2 - x2) + - FXSYS_fabs(y1 + y3 - y2 - y2) + - FXSYS_fabs(x2 + x4 - x3 - x3) + - FXSYS_fabs(y2 + y4 - y3 - y3) <= m_distance_tolerance_manhattan) { - m_points.add(point_type(x1234, y1234, path_flags_jr)); - return; - } - break; - case 1: - if(FXSYS_Mul(d3, d3) <= FXSYS_Mul(m_distance_tolerance_square, - FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy))) { - m_points.add(point_type(x23, y23, path_flags_jr)); - return; - } - break; - case 2: - if(FXSYS_Mul(d2, d2) <= FXSYS_Mul(m_distance_tolerance_square, - FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy))) { - m_points.add(point_type(x23, y23, path_flags_jr)); - return; - } - break; - case 3: - if(FXSYS_Mul(d2 + d3, d2 + d3) <= FXSYS_Mul(m_distance_tolerance_square, - FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy))) { - m_points.add(point_type(x23, y23, path_flags_jr)); - return; - } - break; - } - 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(FX_FLOAT x1, FX_FLOAT y1, - FX_FLOAT x2, FX_FLOAT y2, - FX_FLOAT x3, FX_FLOAT y3, - FX_FLOAT x4, FX_FLOAT y4) -{ - m_points.add(point_type(x1, y1)); - recursive_bezier(x1, y1, x2, y2, x3, y3, x4, y4, 0); - m_points.add(point_type(x4, y4)); -} -} diff --git a/core/src/fxge/agg/agg23/fx_agg_driver.cpp b/core/src/fxge/agg/agg23/fx_agg_driver.cpp deleted file mode 100644 index 0198872995..0000000000 --- a/core/src/fxge/agg/agg23/fx_agg_driver.cpp +++ /dev/null @@ -1,1610 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "../../../../include/fxge/fx_ge.h" -#include "../../dib/dib_int.h" -#include "../../ge/text_int.h" -#include "../../../../include/fxcodec/fx_codec.h" -#include "agg_pixfmt_gray.h" -#include "agg_path_storage.h" -#include "agg_scanline_u.h" -#include "agg_rasterizer_scanline_aa.h" -#include "agg_renderer_scanline.h" -#include "agg_curves.h" -#include "agg_conv_stroke.h" -#include "agg_conv_dash.h" -#include "../include/fx_agg_driver.h" -void _HardClip(FX_FLOAT& x, FX_FLOAT& y) -{ - if (x > 50000) { - x = 50000; - } - if (x < -50000) { - x = -50000; - } - if (y > 50000) { - y = 50000; - } - if (y < -50000) { - y = -50000; - } -} -void CAgg_PathData::BuildPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device) -{ - int nPoints = pPathData->GetPointCount(); - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - for (int i = 0; i < nPoints; i ++) { - FX_FLOAT x = pPoints[i].m_PointX, y = pPoints[i].m_PointY; - if (pObject2Device) { - pObject2Device->Transform(x, y); - } - _HardClip(x, y); - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { - m_PathData.move_to(x, y); - } else if (point_type == FXPT_LINETO) { - if (pPoints[i - 1].m_Flag == FXPT_MOVETO && (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && - pPoints[i].m_PointX == pPoints[i - 1].m_PointX && pPoints[i].m_PointY == pPoints[i - 1].m_PointY) { - x += 1; - } - m_PathData.line_to(x, y); - } else if (point_type == FXPT_BEZIERTO) { - FX_FLOAT x0 = pPoints[i - 1].m_PointX, y0 = pPoints[i - 1].m_PointY; - FX_FLOAT x2 = pPoints[i + 1].m_PointX, y2 = pPoints[i + 1].m_PointY; - FX_FLOAT x3 = pPoints[i + 2].m_PointX, y3 = pPoints[i + 2].m_PointY; - if (pObject2Device) { - pObject2Device->Transform(x0, y0); - pObject2Device->Transform(x2, y2); - pObject2Device->Transform(x3, y3); - } - agg::curve4 curve(x0, y0, x, y, x2, y2, x3, y3); - i += 2; - m_PathData.add_path_curve(curve); - } - if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) { - m_PathData.end_poly(); - } - } -} -namespace agg -{ -template class renderer_scanline_aa_offset -{ -public: - typedef BaseRenderer base_ren_type; - typedef typename base_ren_type::color_type color_type; - renderer_scanline_aa_offset(base_ren_type& ren, unsigned left, unsigned top) : - m_ren(&ren), m_left(left), m_top(top) - {} - void color(const color_type& c) - { - m_color = c; - } - const color_type& color() const - { - return m_color; - } - void prepare(unsigned) {} - template void render(const Scanline& sl) - { - int y = sl.y(); - unsigned num_spans = sl.num_spans(); - typename Scanline::const_iterator span = sl.begin(); - for(;;) { - int x = span->x; - if(span->len > 0) { - m_ren->blend_solid_hspan(x - m_left, y - m_top, (unsigned)span->len, - m_color, - span->covers); - } else { - m_ren->blend_hline(x - m_left, y - m_top, (unsigned)(x - span->len - 1), - m_color, - *(span->covers)); - } - if(--num_spans == 0) { - break; - } - ++span; - } - } -private: - base_ren_type* m_ren; - color_type m_color; - unsigned m_left, m_top; -}; -} -static void RasterizeStroke(agg::rasterizer_scanline_aa& rasterizer, agg::path_storage& path_data, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, FX_FLOAT scale = 1.0f, - FX_BOOL bStrokeAdjust = FALSE, FX_BOOL bTextMode = FALSE) -{ - agg::line_cap_e cap; - switch (pGraphState->m_LineCap) { - case CFX_GraphStateData::LineCapRound: - cap = agg::round_cap; - break; - case CFX_GraphStateData::LineCapSquare: - cap = agg::square_cap; - break; - default: - cap = agg::butt_cap; - break; - } - agg::line_join_e join; - switch (pGraphState->m_LineJoin) { - case CFX_GraphStateData::LineJoinRound: - join = agg::round_join; - break; - case CFX_GraphStateData::LineJoinBevel: - join = agg::bevel_join; - break; - default: - join = agg::miter_join_revert; - break; - } - FX_FLOAT width = pGraphState->m_LineWidth * scale; - FX_FLOAT unit = 1.f; - if (pObject2Device) { - unit = FXSYS_Div(1.0f, (pObject2Device->GetXUnit() + pObject2Device->GetYUnit()) / 2); - } - if (width < unit) { - width = unit; - } - if (pGraphState->m_DashArray == NULL) { - agg::conv_stroke stroke(path_data); - stroke.line_join(join); - stroke.line_cap(cap); - stroke.miter_limit(pGraphState->m_MiterLimit); - stroke.width(width); - rasterizer.add_path_transformed(stroke, pObject2Device); - } else { - typedef agg::conv_dash dash_converter; - dash_converter dash(path_data); - for (int i = 0; i < (pGraphState->m_DashCount + 1) / 2; i ++) { - FX_FLOAT on = pGraphState->m_DashArray[i * 2]; - if (on <= 0.000001f) { - on = 1.0f / 10; - } - FX_FLOAT off = i * 2 + 1 == pGraphState->m_DashCount ? on : - pGraphState->m_DashArray[i * 2 + 1]; - if (off < 0) { - off = 0; - } - dash.add_dash(on * scale, off * scale); - } - dash.dash_start(pGraphState->m_DashPhase * scale); - typedef agg::conv_stroke dash_stroke; - dash_stroke stroke(dash); - stroke.line_join(join); - stroke.line_cap(cap); - stroke.miter_limit(pGraphState->m_MiterLimit); - stroke.width(width); - rasterizer.add_path_transformed(stroke, pObject2Device); - } -} -IFX_RenderDeviceDriver* IFX_RenderDeviceDriver::CreateFxgeDriver(CFX_DIBitmap* pBitmap, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) -{ - return new CFX_AggDeviceDriver(pBitmap, 0, bRgbByteOrder, pOriDevice, bGroupKnockout); -} -CFX_AggDeviceDriver::CFX_AggDeviceDriver(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) -{ - m_pBitmap = pBitmap; - m_DitherBits = dither_bits; - m_pClipRgn = NULL; - m_pPlatformBitmap = NULL; - m_pPlatformGraphics = NULL; - m_pDwRenderTartget = NULL; - m_bRgbByteOrder = bRgbByteOrder; - m_pOriDevice = pOriDevice; - m_bGroupKnockout = bGroupKnockout; - m_FillFlags = 0; - InitPlatform(); -} -CFX_AggDeviceDriver::~CFX_AggDeviceDriver() -{ - if (m_pClipRgn) { - delete m_pClipRgn; - } - for (int i = 0; i < m_StateStack.GetSize(); i ++) - if (m_StateStack[i]) { - delete (CFX_ClipRgn*)m_StateStack[i]; - } - DestroyPlatform(); -} -#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ -void CFX_AggDeviceDriver::InitPlatform() -{ -} -void CFX_AggDeviceDriver::DestroyPlatform() -{ -} -FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, - CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color, - int alpha_flag, void* pIccTransform) -{ - return FALSE; -} -#endif -int CFX_AggDeviceDriver::GetDeviceCaps(int caps_id) -{ - switch (caps_id) { - case FXDC_DEVICE_CLASS: - return FXDC_DISPLAY; - case FXDC_PIXEL_WIDTH: - return m_pBitmap->GetWidth(); - case FXDC_PIXEL_HEIGHT: - return m_pBitmap->GetHeight(); - case FXDC_BITS_PIXEL: - return m_pBitmap->GetBPP(); - case FXDC_HORZ_SIZE: - case FXDC_VERT_SIZE: - return 0; - case FXDC_RENDER_CAPS: { - int flags = FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | FXRC_BLEND_MODE | FXRC_SOFT_CLIP; - if (m_pBitmap->HasAlpha()) { - flags |= FXRC_ALPHA_OUTPUT; - } else if (m_pBitmap->IsAlphaMask()) { - if (m_pBitmap->GetBPP() == 1) { - flags |= FXRC_BITMASK_OUTPUT; - } else { - flags |= FXRC_BYTEMASK_OUTPUT; - } - } - if (m_pBitmap->IsCmykImage()) { - flags |= FXRC_CMYK_OUTPUT; - } - return flags; - } - case FXDC_DITHER_BITS: - return m_DitherBits; - } - return 0; -} -void CFX_AggDeviceDriver::SaveState() -{ - void* pClip = NULL; - if (m_pClipRgn) { - pClip = new CFX_ClipRgn(*m_pClipRgn); - } - m_StateStack.Add(pClip); -} -void CFX_AggDeviceDriver::RestoreState(FX_BOOL bKeepSaved) -{ - if (m_StateStack.GetSize() == 0) { - if (m_pClipRgn) { - delete m_pClipRgn; - m_pClipRgn = NULL; - } - return; - } - CFX_ClipRgn* pSavedClip = (CFX_ClipRgn*)m_StateStack[m_StateStack.GetSize() - 1]; - if (m_pClipRgn) { - delete m_pClipRgn; - m_pClipRgn = NULL; - } - if (bKeepSaved) { - if (pSavedClip) { - m_pClipRgn = new CFX_ClipRgn(*pSavedClip); - } - } else { - m_StateStack.RemoveAt(m_StateStack.GetSize() - 1); - m_pClipRgn = pSavedClip; - } -} -void CFX_AggDeviceDriver::SetClipMask(agg::rasterizer_scanline_aa& rasterizer) -{ - FX_RECT path_rect(rasterizer.min_x(), rasterizer.min_y(), - rasterizer.max_x() + 1, rasterizer.max_y() + 1); - path_rect.Intersect(m_pClipRgn->GetBox()); - CFX_DIBitmapRef mask; - CFX_DIBitmap* pThisLayer = mask.New(); - if (!pThisLayer) { - return; - } - pThisLayer->Create(path_rect.Width(), path_rect.Height(), FXDIB_8bppMask); - pThisLayer->Clear(0); - agg::rendering_buffer raw_buf(pThisLayer->GetBuffer(), pThisLayer->GetWidth(), pThisLayer->GetHeight(), pThisLayer->GetPitch()); - agg::pixfmt_gray8 pixel_buf(raw_buf); - agg::renderer_base base_buf(pixel_buf); - agg::renderer_scanline_aa_offset > final_render(base_buf, path_rect.left, path_rect.top); - final_render.color(agg::gray8(255)); - agg::scanline_u8 scanline; - agg::render_scanlines(rasterizer, scanline, final_render, (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0); - m_pClipRgn->IntersectMaskF(path_rect.left, path_rect.top, mask); -} -FX_BOOL CFX_AggDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - int fill_mode - ) -{ - m_FillFlags = fill_mode; - if (m_pClipRgn == NULL) { - m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); - } - if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { - CFX_FloatRect rectf; - if (pPathData->IsRect(pObject2Device, &rectf)) { - rectf.Intersect(CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - FX_RECT rect = rectf.GetOutterRect(); - m_pClipRgn->IntersectRect(rect); - return TRUE; - } - } - CAgg_PathData path_data; - path_data.BuildPath(pPathData, pObject2Device); - path_data.m_PathData.end_poly(); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - rasterizer.add_path(path_data.m_PathData); - rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING ? agg::fill_non_zero : agg::fill_even_odd); - SetClipMask(rasterizer); - return TRUE; -} -FX_BOOL CFX_AggDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState - ) -{ - if (m_pClipRgn == NULL) { - m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); - } - CAgg_PathData path_data; - path_data.BuildPath(pPathData, NULL); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - RasterizeStroke(rasterizer, path_data.m_PathData, pObject2Device, pGraphState); - rasterizer.filling_rule(agg::fill_non_zero); - SetClipMask(rasterizer); - return TRUE; -} -class CFX_Renderer -{ -private: - int m_Alpha, - m_Red, - m_Green, - m_Blue, - m_Gray; - FX_DWORD m_Color; - FX_BOOL m_bFullCover; - FX_BOOL m_bRgbByteOrder; - CFX_DIBitmap* m_pOriDevice; - FX_RECT m_ClipBox; - const CFX_DIBitmap* m_pClipMask; - CFX_DIBitmap* m_pDevice; - const CFX_ClipRgn* m_pClipRgn; - void (CFX_Renderer::*composite_span)(uint8_t*, int, int, int, uint8_t*, int, int, uint8_t*, uint8_t*); -public: - void prepare(unsigned) {} - void CompositeSpan(uint8_t* dest_scan, uint8_t* ori_scan, int Bpp, FX_BOOL bDestAlpha, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (Bpp) { - dest_scan += col_start * Bpp; - ori_scan += col_start * Bpp; - } else { - dest_scan += col_start / 8; - ori_scan += col_start / 8; - } - if (m_bRgbByteOrder) { - if (Bpp == 4 && bDestAlpha) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - uint8_t dest_alpha = ori_scan[3] + src_alpha - ori_scan[3] * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (m_bFullCover) { - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio); - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio); - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio); - dest_scan++; - ori_scan++; - } else { - int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio); - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio); - ori_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, r, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]); - dest_scan += 2; - } - } - return; - } else if (Bpp == 3 || Bpp == 4) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255 ; - } else { - src_alpha = m_Alpha; - } - int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - int b = FXDIB_ALPHA_MERGE(*ori_scan, m_Blue, src_alpha); - ori_scan += Bpp - 2; - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, r, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]); - dest_scan += Bpp - 2; - } - } - return; - } - if (Bpp == 4 && bDestAlpha) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - int src_alpha_covered = src_alpha * cover_scan[col] / 255; - if (src_alpha_covered == 0) { - dest_scan += 4; - continue; - } - if (cover_scan[col] == 255) { - dest_scan[3] = src_alpha_covered; - *dest_scan ++ = m_Blue; - *dest_scan ++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } else { - if (dest_scan[3] == 0) { - dest_scan[3] = src_alpha_covered; - *dest_scan ++ = m_Blue; - *dest_scan ++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - uint8_t cover = cover_scan[col]; - dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover); - dest_scan += 2; - } - } - return; - } else if (Bpp == 3 || Bpp == 4) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - if (m_bFullCover) { - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); - dest_scan += Bpp - 2; - ori_scan += Bpp - 2; - continue; - } - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); - ori_scan += Bpp - 2; - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, b, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]); - dest_scan += Bpp - 2; - continue; - } - return; - } else if (Bpp == 1) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - if (m_bFullCover) { - *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - } else { - int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan[col]); - dest_scan++; - } - } - } else { - int index = 0; - if (m_pDevice->GetPalette() == NULL) { - index = ((uint8_t)m_Color == 0xff) ? 1 : 0; - } else { - for (int i = 0; i < 2; i ++) - if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) { - index = i; - } - } - uint8_t* dest_scan1 = dest_scan; - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (!index) { - *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); - } else { - *dest_scan1 |= 1 << (7 - (col + span_left) % 8); - } - } - dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; - } - } - } - void CompositeSpan1bpp(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - ASSERT(!m_pDevice->IsCmykImage()); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start / 8; - int index = 0; - if (m_pDevice->GetPalette() == NULL) { - index = ((uint8_t)m_Color == 0xff) ? 1 : 0; - } else { - for (int i = 0; i < 2; i ++) - if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) { - index = i; - } - } - uint8_t* dest_scan1 = dest_scan; - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (!index) { - *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); - } else { - *dest_scan1 |= 1 << (7 - (col + span_left) % 8); - } - } - dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; - } - } - void CompositeSpanGray(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start; - if (dest_extra_alpha_scan) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *dest_scan = m_Gray; - *dest_extra_alpha_scan = m_Alpha; - } else { - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); - dest_scan ++; - continue; - } - } - dest_extra_alpha_scan ++; - dest_scan ++; - } - } else { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (src_alpha == 255) { - *dest_scan = m_Gray; - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); - } - } - dest_scan ++; - } - } - } - void CompositeSpanARGB(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start * Bpp; - if (m_bRgbByteOrder) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *(FX_DWORD*)dest_scan = m_Color; - } else { - uint8_t dest_alpha = dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan += 2; - continue; - } - } - dest_scan += 4; - } - return; - } - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *(FX_DWORD*)dest_scan = m_Color; - } else { - if (dest_scan[3] == 0) { - dest_scan[3] = src_alpha; - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - uint8_t dest_alpha = dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan += 2; - continue; - } - } - dest_scan += Bpp; - } - } - void CompositeSpanRGB(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start * Bpp; - if (m_bRgbByteOrder) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (src_alpha == 255) { - if (Bpp == 4) { - *(FX_DWORD*)dest_scan = m_Color; - } else if (Bpp == 3) { - *dest_scan++ = m_Red; - *dest_scan++ = m_Green; - *dest_scan++ = m_Blue; - continue; - } - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan += Bpp - 2; - continue; - } - } - dest_scan += Bpp; - } - return; - } - if (Bpp == 3 && dest_extra_alpha_scan) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *dest_scan++ = (uint8_t)m_Blue; - *dest_scan++ = (uint8_t)m_Green; - *dest_scan++ = (uint8_t)m_Red; - *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; - continue; - } else { - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - continue; - } - } - dest_extra_alpha_scan++; - dest_scan += Bpp; - } - } else { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - if (Bpp == 4) { - *(FX_DWORD*)dest_scan = m_Color; - } else if (Bpp == 3) { - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan++ = m_Red; - continue; - } - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan += Bpp - 2; - continue; - } - } - dest_scan += Bpp; - } - } - } - void CompositeSpanCMYK(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start * 4; - if (dest_extra_alpha_scan) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *(FX_CMYK*)dest_scan = m_Color; - *dest_extra_alpha_scan = (uint8_t)m_Alpha; - } else { - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); - dest_scan ++; - continue; - } - } - dest_extra_alpha_scan++; - dest_scan += 4; - } - } else { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (src_alpha == 255) { - *(FX_CMYK*)dest_scan = m_Color; - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); - dest_scan ++; - continue; - } - } - dest_scan += 4; - } - } - } - template void render(const Scanline& sl) - { - if (m_pOriDevice == NULL && composite_span == NULL) { - return; - } - int y = sl.y(); - if (y < m_ClipBox.top || y >= m_ClipBox.bottom) { - return; - } - uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * y; - uint8_t* dest_scan_extra_alpha = NULL; - CFX_DIBitmap* pAlphaMask = m_pDevice->m_pAlphaMask; - if (pAlphaMask) { - dest_scan_extra_alpha = pAlphaMask->GetBuffer() + pAlphaMask->GetPitch() * y; - } - uint8_t* ori_scan = NULL; - if (m_pOriDevice) { - ori_scan = m_pOriDevice->GetBuffer() + m_pOriDevice->GetPitch() * y; - } - int Bpp = m_pDevice->GetBPP() / 8; - FX_BOOL bDestAlpha = m_pDevice->HasAlpha() || m_pDevice->IsAlphaMask(); - unsigned num_spans = sl.num_spans(); - typename Scanline::const_iterator span = sl.begin(); - while (1) { - int x = span->x; - ASSERT(span->len > 0); - uint8_t* dest_pos = NULL; - uint8_t* dest_extra_alpha_pos = NULL; - uint8_t* ori_pos = NULL; - if (Bpp) { - ori_pos = ori_scan ? ori_scan + x * Bpp : NULL; - dest_pos = dest_scan + x * Bpp; - dest_extra_alpha_pos = dest_scan_extra_alpha ? dest_scan_extra_alpha + x : NULL; - } else { - dest_pos = dest_scan + x / 8; - ori_pos = ori_scan ? ori_scan + x / 8 : NULL; - } - uint8_t* clip_pos = NULL; - if (m_pClipMask) { - clip_pos = m_pClipMask->GetBuffer() + (y - m_ClipBox.top) * m_pClipMask->GetPitch() + x - m_ClipBox.left; - } - if (ori_pos) { - CompositeSpan(dest_pos, ori_pos, Bpp, bDestAlpha, x, span->len, span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos); - } else { - (this->*composite_span)(dest_pos, Bpp, x, span->len, span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos, dest_extra_alpha_pos); - } - if(--num_spans == 0) { - break; - } - ++span; - } - } - - FX_BOOL Init(CFX_DIBitmap* pDevice, CFX_DIBitmap* pOriDevice, const CFX_ClipRgn* pClipRgn, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bRgbByteOrder, - int alpha_flag = 0, void* pIccTransform = NULL) - { - m_pDevice = pDevice; - m_pClipRgn = pClipRgn; - composite_span = NULL; - m_bRgbByteOrder = bRgbByteOrder; - m_pOriDevice = pOriDevice; - if (m_pClipRgn) { - m_ClipBox = m_pClipRgn->GetBox(); - } else { - m_ClipBox.left = m_ClipBox.top = 0; - m_ClipBox.right = m_pDevice->GetWidth(); - m_ClipBox.bottom = m_pDevice->GetHeight(); - } - m_pClipMask = NULL; - if (m_pClipRgn && m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { - m_pClipMask = m_pClipRgn->GetMask(); - } - m_bFullCover = bFullCover; - FX_BOOL bObjectCMYK = FXGETFLAG_COLORTYPE(alpha_flag); - FX_BOOL bDeviceCMYK = pDevice->IsCmykImage(); - m_Alpha = bObjectCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - ICodec_IccModule* pIccModule = NULL; - if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - pIccTransform = NULL; - } else { - pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - } - if (m_pDevice->GetBPP() == 8) { - ASSERT(!m_bRgbByteOrder); - composite_span = &CFX_Renderer::CompositeSpanGray; - if (m_pDevice->IsAlphaMask()) { - m_Gray = 255; - } else { - if (pIccTransform) { - uint8_t gray; - color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, &gray, (const uint8_t*)&color, 1); - m_Gray = gray; - } else { - if (bObjectCMYK) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), - r, g, b); - m_Gray = FXRGB2GRAY(r, g, b); - } else { - m_Gray = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); - } - } - } - return TRUE; - } - if (bDeviceCMYK) { - ASSERT(!m_bRgbByteOrder); - composite_span = &CFX_Renderer::CompositeSpanCMYK; - if (bObjectCMYK) { - m_Color = FXCMYK_TODIB(color); - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&m_Color, 1); - } - } else { - if (!pIccTransform) { - return FALSE; - } - color = FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&color, 1); - } - m_Red = ((uint8_t*)&m_Color)[0]; - m_Green = ((uint8_t*)&m_Color)[1]; - m_Blue = ((uint8_t*)&m_Color)[2]; - m_Gray = ((uint8_t*)&m_Color)[3]; - } else { - composite_span = (pDevice->GetFormat() == FXDIB_Argb) ? &CFX_Renderer::CompositeSpanARGB : &CFX_Renderer::CompositeSpanRGB; - if (pIccTransform) { - color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&color, 1); - ((uint8_t*)&m_Color)[3] = m_Alpha; - m_Red = ((uint8_t*)&m_Color)[2]; - m_Green = ((uint8_t*)&m_Color)[1]; - m_Blue = ((uint8_t*)&m_Color)[0]; - if (m_bRgbByteOrder) { - m_Color = FXARGB_TODIB(m_Color); - m_Color = FXARGB_TOBGRORDERDIB(m_Color); - } - } else { - if (bObjectCMYK) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), - r, g, b); - m_Color = FXARGB_MAKE(m_Alpha, r, g, b); - if (m_bRgbByteOrder) { - m_Color = FXARGB_TOBGRORDERDIB(m_Color); - } else { - m_Color = FXARGB_TODIB(m_Color); - } - m_Red = r; - m_Green = g; - m_Blue = b; - } else { - if (m_bRgbByteOrder) { - m_Color = FXARGB_TOBGRORDERDIB(color); - } else { - m_Color = FXARGB_TODIB(color); - } - ArgbDecode(color, m_Alpha, m_Red, m_Green, m_Blue); - } - } - } - if (m_pDevice->GetBPP() == 1) { - composite_span = &CFX_Renderer::CompositeSpan1bpp; - } - return TRUE; - } -}; -FX_BOOL CFX_AggDeviceDriver::RenderRasterizer(agg::rasterizer_scanline_aa& rasterizer, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bGroupKnockout, - int alpha_flag, void* pIccTransform) -{ - CFX_DIBitmap* pt = bGroupKnockout ? m_pOriDevice : NULL; - CFX_Renderer render; - if (!render.Init(m_pBitmap, pt, m_pClipRgn, color, bFullCover, m_bRgbByteOrder, alpha_flag, pIccTransform)) { - return FALSE; - } - agg::scanline_u8 scanline; - agg::render_scanlines(rasterizer, scanline, render, (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0); - return TRUE; -} -FX_BOOL CFX_AggDeviceDriver::DrawPath(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, - FX_DWORD fill_color, - FX_DWORD stroke_color, - int fill_mode, - int alpha_flag, - void* pIccTransform, - int blend_type - ) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { - return FALSE; - } - if (GetBuffer() == NULL) { - return TRUE; - } - m_FillFlags = fill_mode; - if ((fill_mode & 3) && fill_color) { - CAgg_PathData path_data; - path_data.BuildPath(pPathData, pObject2Device); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - rasterizer.add_path(path_data.m_PathData); - rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING ? agg::fill_non_zero : agg::fill_even_odd); - if (!RenderRasterizer(rasterizer, fill_color, fill_mode & FXFILL_FULLCOVER, FALSE, alpha_flag, pIccTransform)) { - return FALSE; - } - } - int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_STROKE(alpha_flag) : FXARGB_A(stroke_color); - if (pGraphState && stroke_alpha) { - if (fill_mode & FX_ZEROAREA_FILL) { - CAgg_PathData path_data; - path_data.BuildPath(pPathData, pObject2Device); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - RasterizeStroke(rasterizer, path_data.m_PathData, NULL, pGraphState, 1, FALSE, fill_mode & FX_STROKE_TEXT_MODE); - int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 | FXGETFLAG_ALPHA_STROKE(alpha_flag); - if (!RenderRasterizer(rasterizer, stroke_color, fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout, fill_flag, pIccTransform)) { - return FALSE; - } - return TRUE; - } - CFX_AffineMatrix matrix1, matrix2; - if (pObject2Device) { - matrix1.a = FX_MAX(FXSYS_fabs(pObject2Device->a), FXSYS_fabs(pObject2Device->b)); - matrix1.d = matrix1.a; - matrix2.Set(pObject2Device->a / matrix1.a, pObject2Device->b / matrix1.a, - pObject2Device->c / matrix1.d, pObject2Device->d / matrix1.d, - 0, 0); - CFX_AffineMatrix mtRervese; - mtRervese.SetReverse(matrix2); - matrix1 = *pObject2Device; - matrix1.Concat(mtRervese); - } - CAgg_PathData path_data; - path_data.BuildPath(pPathData, &matrix1); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - RasterizeStroke(rasterizer, path_data.m_PathData, &matrix2, pGraphState, matrix1.a, FALSE, fill_mode & FX_STROKE_TEXT_MODE); - int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 | FXGETFLAG_ALPHA_STROKE(alpha_flag); - if (!RenderRasterizer(rasterizer, stroke_color, fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout, fill_flag, pIccTransform)) { - return FALSE; - } - } - return TRUE; -} -void RgbByteOrderSetPixel(CFX_DIBitmap* pBitmap, int x, int y, FX_DWORD argb) -{ - if (x < 0 || x >= pBitmap->GetWidth() || y < 0 || y >= pBitmap->GetHeight()) { - return; - } - uint8_t* pos = (uint8_t*)pBitmap->GetBuffer() + y * pBitmap->GetPitch() + x * pBitmap->GetBPP() / 8; - if (pBitmap->GetFormat() == FXDIB_Argb) { - FXARGB_SETRGBORDERDIB(pos, ArgbGamma(argb)); - } else { - int alpha = FXARGB_A(argb); - pos[0] = (FXARGB_R(argb) * alpha + pos[0] * (255 - alpha)) / 255; - pos[1] = (FXARGB_G(argb) * alpha + pos[1] * (255 - alpha)) / 255; - pos[2] = (FXARGB_B(argb) * alpha + pos[2] * (255 - alpha)) / 255; - } -} -void RgbByteOrderCompositeRect(CFX_DIBitmap* pBitmap, int left, int top, int width, int height, FX_ARGB argb) -{ - int src_alpha = FXARGB_A(argb); - if (src_alpha == 0) { - return; - } - FX_RECT rect(left, top, left + width, top + height); - rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); - width = rect.Width(); - int src_r = FXARGB_R(argb), src_g = FXARGB_G(argb), src_b = FXARGB_B(argb); - int Bpp = pBitmap->GetBPP() / 8; - FX_BOOL bAlpha = pBitmap->HasAlpha(); - int dib_argb = FXARGB_TOBGRORDERDIB(argb); - uint8_t* pBuffer = pBitmap->GetBuffer(); - if (src_alpha == 255) { - for (int row = rect.top; row < rect.bottom; row ++) { - uint8_t* dest_scan = pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp; - if (Bpp == 4) { - FX_DWORD* scan = (FX_DWORD*)dest_scan; - for (int col = 0; col < width; col ++) { - *scan ++ = dib_argb; - } - } else { - for (int col = 0; col < width; col ++) { - *dest_scan ++ = src_r; - *dest_scan ++ = src_g; - *dest_scan ++ = src_b; - } - } - } - return; - } - src_r = FX_GAMMA(src_r); - src_g = FX_GAMMA(src_g); - src_b = FX_GAMMA(src_b); - for (int row = rect.top; row < rect.bottom; row ++) { - uint8_t* dest_scan = pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp; - if (bAlpha) { - for (int col = 0; col < width; col ++) { - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); - dest_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan += 2; - } - } else { - for (int col = 0; col < width; col ++) { - *dest_scan = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_r, src_alpha)); - dest_scan++; - *dest_scan = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_g, src_alpha)); - dest_scan++; - *dest_scan = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_b, src_alpha)); - dest_scan++; - if (Bpp == 4) { - dest_scan++; - } - } - } - } -} -void RgbByteOrderTransferBitmap(CFX_DIBitmap* pBitmap, int dest_left, int dest_top, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top) -{ - if (pBitmap == NULL) { - return; - } - pBitmap->GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), src_left, src_top, NULL); - if (width == 0 || height == 0) { - return; - } - int Bpp = pBitmap->GetBPP() / 8; - FXDIB_Format dest_format = pBitmap->GetFormat(); - FXDIB_Format src_format = pSrcBitmap->GetFormat(); - int pitch = pBitmap->GetPitch(); - uint8_t* buffer = pBitmap->GetBuffer(); - if (dest_format == src_format) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = buffer + (dest_top + row) * pitch + dest_left * Bpp; - uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; - if (Bpp == 4) { - for (int col = 0; col < width; col ++) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_scan[3], src_scan[0], src_scan[1], src_scan[2])); - dest_scan += 4; - src_scan += 4; - } - } else { - for (int col = 0; col < width; col ++) { - *dest_scan++ = src_scan[2]; - *dest_scan++ = src_scan[1]; - *dest_scan++ = src_scan[0]; - src_scan += 3; - } - } - } - return; - } - uint8_t* dest_buf = buffer + dest_top * pitch + dest_left * Bpp; - if (dest_format == FXDIB_Rgb) { - if (src_format == FXDIB_Rgb32) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * pitch; - uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 4; - for (int col = 0; col < width; col ++) { - *dest_scan++ = src_scan[2]; - *dest_scan++ = src_scan[1]; - *dest_scan++ = src_scan[0]; - src_scan += 4; - } - } - } else { - ASSERT(FALSE); - } - } else if (dest_format == FXDIB_Argb || dest_format == FXDIB_Rgb32) { - if (src_format == FXDIB_Rgb) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = (uint8_t*)(dest_buf + row * pitch); - uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 3; - if (src_format == FXDIB_Argb) { - for (int col = 0; col < width; col ++) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, FX_GAMMA(src_scan[0]), FX_GAMMA(src_scan[1]), FX_GAMMA(src_scan[2]))); - dest_scan += 4; - src_scan += 3; - } - } else { - for (int col = 0; col < width; col ++) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1], src_scan[2])); - dest_scan += 4; - src_scan += 3; - } - } - } - } else if (src_format == FXDIB_Rgb32) { - ASSERT(dest_format == FXDIB_Argb); - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * pitch; - uint8_t* src_scan = (uint8_t*)(pSrcBitmap->GetScanline(src_top + row) + src_left * 4); - for (int col = 0; col < width; col++) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1], src_scan[2])); - src_scan += 4; - dest_scan += 4; - } - } - } - } else { - ASSERT(FALSE); - } -} -FX_ARGB _DefaultCMYK2ARGB(FX_CMYK cmyk, uint8_t alpha) -{ - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), - r, g, b); - return ArgbEncode(alpha, r, g, b); -} -FX_BOOL _DibSetPixel(CFX_DIBitmap* pDevice, int x, int y, FX_DWORD color, int alpha_flag, void* pIccTransform) -{ - FX_BOOL bObjCMYK = FXGETFLAG_COLORTYPE(alpha_flag); - int alpha = bObjCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&color, (uint8_t*)&color, 1); - color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - if (!pDevice->IsCmykImage()) { - color = (color & 0xffffff) | (alpha << 24); - } - } else { - if (pDevice->IsCmykImage()) { - if (!bObjCMYK) { - return FALSE; - } - } else { - if (bObjCMYK) { - color = _DefaultCMYK2ARGB(color, alpha); - } - } - } - pDevice->SetPixel(x, y, color); - if (pDevice->m_pAlphaMask) { - pDevice->m_pAlphaMask->SetPixel(x, y, alpha << 24); - } - return TRUE; -} -FX_BOOL CFX_AggDeviceDriver::SetPixel(int x, int y, FX_DWORD color, int alpha_flag, void* pIccTransform) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - pIccTransform = NULL; - } - if (m_pClipRgn == NULL) { - if (m_bRgbByteOrder) { - RgbByteOrderSetPixel(m_pBitmap, x, y, color); - } else { - return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); - } - } else if (m_pClipRgn->GetBox().Contains(x, y)) { - if (m_pClipRgn->GetType() == CFX_ClipRgn::RectI) { - if (m_bRgbByteOrder) { - RgbByteOrderSetPixel(m_pBitmap, x, y, color); - } else { - return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); - } - } else if (m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { - const CFX_DIBitmap* pMask = m_pClipRgn->GetMask(); - FX_BOOL bCMYK = FXGETFLAG_COLORTYPE(alpha_flag); - int new_alpha = bCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - new_alpha = new_alpha * pMask->GetScanline(y)[x] / 255; - if (m_bRgbByteOrder) { - RgbByteOrderSetPixel(m_pBitmap, x, y, (color & 0xffffff) | (new_alpha << 24)); - return TRUE; - } - if (bCMYK) { - FXSETFLAG_ALPHA_FILL(alpha_flag, new_alpha); - } else { - color = (color & 0xffffff) | (new_alpha << 24); - } - return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); - } - } - return TRUE; -} -FX_BOOL CFX_AggDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { - return FALSE; - } - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - FX_RECT clip_rect; - GetClipBox(&clip_rect); - FX_RECT draw_rect = clip_rect; - if (pRect) { - draw_rect.Intersect(*pRect); - } - if (draw_rect.IsEmpty()) { - return TRUE; - } - if (m_pClipRgn == NULL || m_pClipRgn->GetType() == CFX_ClipRgn::RectI) { - if (m_bRgbByteOrder) { - RgbByteOrderCompositeRect(m_pBitmap, draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), fill_color); - } else { - m_pBitmap->CompositeRect(draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), fill_color, alpha_flag, pIccTransform); - } - return TRUE; - } - m_pBitmap->CompositeMask(draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), (const CFX_DIBitmap*)m_pClipRgn->GetMask(), - fill_color, draw_rect.left - clip_rect.left, draw_rect.top - clip_rect.top, FXDIB_BLEND_NORMAL, NULL, m_bRgbByteOrder, alpha_flag, pIccTransform); - return TRUE; -} -FX_BOOL CFX_AggDeviceDriver::GetClipBox(FX_RECT* pRect) -{ - if (m_pClipRgn == NULL) { - pRect->left = pRect->top = 0; - pRect->right = GetDeviceCaps(FXDC_PIXEL_WIDTH); - pRect->bottom = GetDeviceCaps(FXDC_PIXEL_HEIGHT); - return TRUE; - } - *pRect = m_pClipRgn->GetBox(); - return TRUE; -} -FX_BOOL CFX_AggDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform, FX_BOOL bDEdge) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - if (bDEdge) { - if (m_bRgbByteOrder) { - RgbByteOrderTransferBitmap(pBitmap, 0, 0, pBitmap->GetWidth(), pBitmap->GetHeight(), m_pBitmap, left, top); - } else { - return pBitmap->TransferBitmap(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight(), m_pBitmap, left, top, pIccTransform); - } - return TRUE; - } - FX_RECT rect(left, top, left + pBitmap->GetWidth(), top + pBitmap->GetHeight()); - CFX_DIBitmap *pBack = NULL; - if (m_pOriDevice) { - pBack = m_pOriDevice->Clone(&rect); - if (!pBack) { - return TRUE; - } - pBack->CompositeBitmap(0, 0, pBack->GetWidth(), pBack->GetHeight(), m_pBitmap, 0, 0); - } else { - pBack = m_pBitmap->Clone(&rect); - } - if (!pBack) { - return TRUE; - } - FX_BOOL bRet = TRUE; - left = left >= 0 ? 0 : left; - top = top >= 0 ? 0 : top; - if (m_bRgbByteOrder) { - RgbByteOrderTransferBitmap(pBitmap, 0, 0, rect.Width(), rect.Height(), pBack, left, top); - } else { - bRet = pBitmap->TransferBitmap(0, 0, rect.Width(), rect.Height(), pBack, left, top, pIccTransform); - } - delete pBack; - return bRet; -} -FX_BOOL CFX_AggDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD argb, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - if (pBitmap->IsAlphaMask()) - return m_pBitmap->CompositeMask(left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, argb, - pSrcRect->left, pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder, alpha_flag, pIccTransform); - return m_pBitmap->CompositeBitmap(left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, - pSrcRect->left, pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder, pIccTransform); -} -FX_BOOL CFX_AggDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD argb, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - if (dest_width == pSource->GetWidth() && dest_height == pSource->GetHeight()) { - FX_RECT rect(0, 0, dest_width, dest_height); - return SetDIBits(pSource, argb, &rect, dest_left, dest_top, blend_type, alpha_flag, pIccTransform); - } - FX_RECT dest_rect(dest_left, dest_top, dest_left + dest_width, dest_top + dest_height); - dest_rect.Normalize(); - FX_RECT dest_clip = dest_rect; - dest_clip.Intersect(*pClipRect); - CFX_BitmapComposer composer; - composer.Compose(m_pBitmap, m_pClipRgn, 255, argb, dest_clip, FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_flag, pIccTransform, blend_type); - dest_clip.Offset(-dest_rect.left, -dest_rect.top); - CFX_ImageStretcher stretcher; - if (stretcher.Start(&composer, pSource, dest_width, dest_height, dest_clip, flags)) { - stretcher.Continue(NULL); - } - return TRUE; -} -FX_BOOL CFX_AggDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_alpha, FX_DWORD argb, - const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, void*& handle, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - CFX_ImageRenderer* pRenderer = new CFX_ImageRenderer; - pRenderer->Start(m_pBitmap, m_pClipRgn, pSource, bitmap_alpha, argb, pMatrix, render_flags, m_bRgbByteOrder, alpha_flag, pIccTransform); - handle = pRenderer; - return TRUE; -} -FX_BOOL CFX_AggDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - return ((CFX_ImageRenderer*)pHandle)->Continue(pPause); -} -void CFX_AggDeviceDriver::CancelDIBits(void* pHandle) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return; - } - delete (CFX_ImageRenderer*)pHandle; -} -CFX_FxgeDevice::CFX_FxgeDevice() -{ - m_bOwnedBitmap = FALSE; -} -FX_BOOL CFX_FxgeDevice::Attach(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) -{ - if (pBitmap == NULL) { - return FALSE; - } - SetBitmap(pBitmap); - IFX_RenderDeviceDriver* pDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); - SetDeviceDriver(pDriver); - return TRUE; -} -FX_BOOL CFX_FxgeDevice::Create(int width, int height, FXDIB_Format format, int dither_bits, CFX_DIBitmap* pOriDevice) -{ - m_bOwnedBitmap = TRUE; - CFX_DIBitmap* pBitmap = new CFX_DIBitmap; - if (!pBitmap->Create(width, height, format)) { - delete pBitmap; - return FALSE; - } - SetBitmap(pBitmap); - IFX_RenderDeviceDriver* pDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, FALSE, pOriDevice, FALSE); - SetDeviceDriver(pDriver); - return TRUE; -} -CFX_FxgeDevice::~CFX_FxgeDevice() -{ - if (m_bOwnedBitmap && GetBitmap()) { - delete GetBitmap(); - } -} diff --git a/core/src/fxge/agg/agg23/fx_agg_path_storage.cpp b/core/src/fxge/agg/agg23/fx_agg_path_storage.cpp deleted file mode 100644 index 8a876210b7..0000000000 --- a/core/src/fxge/agg/agg23/fx_agg_path_storage.cpp +++ /dev/null @@ -1,98 +0,0 @@ - -//---------------------------------------------------------------------------- -// XYQ: 2006-01-22 Copied from AGG project. -// TODO: This file uses intensive floating point operations, so it's NOT suitable -// for platforms like Symbian OS. We need to change to FIX format. -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Class path_storage -// -//---------------------------------------------------------------------------- -#include "../../../../include/fxcrt/fx_basic.h" -#include "agg_path_storage.h" -#include "agg_math.h" -namespace agg -{ -path_storage::~path_storage() -{ - if(m_total_blocks) { - FX_FLOAT** coord_blk = m_coord_blocks + m_total_blocks - 1; - while(m_total_blocks--) { - FX_Free(*coord_blk); - --coord_blk; - } - FX_Free(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) -{ -} -void path_storage::allocate_block(unsigned nb) -{ - if(nb >= m_max_blocks) { - FX_FLOAT** new_coords = - FX_Alloc2D(FX_FLOAT*, m_max_blocks + block_pool, 2); - unsigned char** new_cmds = - (unsigned char**)(new_coords + m_max_blocks + block_pool); - if(m_coord_blocks) { - FXSYS_memcpy(new_coords, - m_coord_blocks, - m_max_blocks * sizeof(FX_FLOAT*)); - FXSYS_memcpy(new_cmds, - m_cmd_blocks, - m_max_blocks * sizeof(unsigned char*)); - FX_Free(m_coord_blocks); - } - m_coord_blocks = new_coords; - m_cmd_blocks = new_cmds; - m_max_blocks += block_pool; - } - m_coord_blocks[nb] = - FX_Alloc( FX_FLOAT, block_size * 2 + - block_size / - (sizeof(FX_FLOAT) / 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::curve4(FX_FLOAT x_ctrl1, FX_FLOAT y_ctrl1, - FX_FLOAT x_ctrl2, FX_FLOAT y_ctrl2, - FX_FLOAT x_to, FX_FLOAT 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::end_poly() -{ - if(m_total_vertices) { - if(is_vertex(command(m_total_vertices - 1))) { - add_vertex(0, 0, path_cmd_end_poly | path_flags_close); - } - } -} -} diff --git a/core/src/fxge/agg/agg23/fx_agg_rasterizer_scanline_aa.cpp b/core/src/fxge/agg/agg23/fx_agg_rasterizer_scanline_aa.cpp deleted file mode 100644 index b26e2595c1..0000000000 --- a/core/src/fxge/agg/agg23/fx_agg_rasterizer_scanline_aa.cpp +++ /dev/null @@ -1,489 +0,0 @@ - -//---------------------------------------------------------------------------- -// XYQ: 2006-01-22 Copied from AGG project. -// This file uses only integer data, so it's suitable for all platforms. -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// -// 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/fxcrt/fx_ext.h" -#include -#include "agg_rasterizer_scanline_aa.h" -namespace agg -{ -AGG_INLINE void cell_aa::set_cover(int c, int a) -{ - cover = c; - area = a; -} -AGG_INLINE void cell_aa::add_cover(int c, int a) -{ - cover += c; - area += a; -} -AGG_INLINE void cell_aa::set_coord(int cx, int cy) -{ - x = cx; - y = cy; -} -AGG_INLINE void cell_aa::set(int cx, int cy, int c, int a) -{ - x = cx; - y = cy; - cover = c; - area = a; -} -outline_aa::~outline_aa() -{ - if(m_num_blocks) { - cell_aa** ptr = m_cells + m_num_blocks - 1; - while(m_num_blocks--) { - FX_Free(*ptr); - ptr--; - } - FX_Free(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_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 = FX_Alloc( cell_aa*, m_max_blocks + cell_block_pool); - if(m_cells) { - FXSYS_memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_aa*)); - FX_Free(m_cells); - } - m_cells = new_cells; - m_max_blocks += cell_block_pool; - } - m_cells[m_num_blocks++] = FX_Alloc(cell_aa, cell_block_size); - } - m_cur_cell_ptr = m_cells[m_cur_block++]; -} -AGG_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; - } -} -AGG_INLINE void outline_aa::set_cur_cell(int x, int y) -{ - if(m_cur_cell.x != x || m_cur_cell.y != y) { - add_cur_cell(); - m_cur_cell.set(x, y, 0, 0); - if(x < m_min_x) { - m_min_x = x; - } - if(x > m_max_x) { - m_max_x = x; - } - if(y < m_min_y) { - m_min_y = y; - } - if(y > m_max_y) { - m_max_y = y; - } - } -} -AGG_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; - if(y1 == y2) { - set_cur_cell(ex2, ey); - return; - } - if(ex1 == ex2) { - delta = y2 - y1; - m_cur_cell.add_cover(delta, (fx1 + fx2) * delta); - return; - } - 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) -{ - enum dx_limit_e { dx_limit = 16384 << poly_base_shift }; - int dx = x2 - x1; - if(dx >= dx_limit || dx <= -dx_limit) { - int cx = (x1 + x2) >> 1; - int cy = (y1 + y2) >> 1; - render_line(x1, y1, cx, cy); - render_line(cx, cy, x2, y2); - } - int dy = y2 - y1; - 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 x_from, x_to; - int p, rem, mod, lift, delta, first, incr; - if(ey1 == ey2) { - render_hline(ey1, x1, fy1, x2, fy2); - return; - } - 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; - 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) { - m_cur_cell.set_cover(delta, area); - ey1 += incr; - set_cur_cell(ex, ey1); - } - delta = fy2 - poly_base_size + first; - m_cur_cell.add_cover(delta, two_fx * delta); - return; - } - 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; -} -template static AGG_INLINE void swap_cells(T* a, T* b) -{ - T temp = *a; - *a = *b; - *b = temp; -} -enum { - qsort_threshold = 9 -}; -static void 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) { - pivot = base + len / 2; - swap_cells(base, pivot); - i = base + 1; - j = limit - 1; - 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); - 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 { - 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; - } - } - } -} -void outline_aa::sort_cells() -{ - if(m_sorted) { - return; - } - add_cur_cell(); - if(m_num_cells == 0) { - return; - } - m_sorted_cells.allocate(m_num_cells, 16); - if (m_max_y > 0 && m_min_y < 0 && -m_min_y > INT_MAX - m_max_y) { - return; - } - unsigned size = m_max_y - m_min_y; - if (size + 1 < size) { - return; - } - size++; - m_sorted_y.allocate(size, 16); - m_sorted_y.zero(); - cell_aa** block_ptr = m_cells; - cell_aa* cell_ptr = NULL; - 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; - } - } - i = m_num_cells & cell_block_mask; - if (i) { - cell_ptr = *block_ptr++; - } - while(i--) { - m_sorted_y[cell_ptr->y - m_min_y].start++; - ++cell_ptr; - } - 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; - } - 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& cur_y = m_sorted_y[cell_ptr->y - m_min_y]; - m_sorted_cells[cur_y.start + cur_y.num] = cell_ptr; - ++cur_y.num; - ++cell_ptr; - } - } - i = m_num_cells & cell_block_mask; - if (i) { - cell_ptr = *block_ptr++; - } - while(i--) { - sorted_y& cur_y = m_sorted_y[cell_ptr->y - m_min_y]; - m_sorted_cells[cur_y.start + cur_y.num] = cell_ptr; - ++cur_y.num; - ++cell_ptr; - } - for(i = 0; i < m_sorted_y.size(); i++) { - const sorted_y& cur_y = m_sorted_y[i]; - if(cur_y.num) { - qsort_cells(m_sorted_cells.data() + cur_y.start, cur_y.num); - } - } - m_sorted = true; -} -} diff --git a/core/src/fxge/agg/agg23/fx_agg_vcgen_dash.cpp b/core/src/fxge/agg/agg23/fx_agg_vcgen_dash.cpp deleted file mode 100644 index 0b6c29051b..0000000000 --- a/core/src/fxge/agg/agg23/fx_agg_vcgen_dash.cpp +++ /dev/null @@ -1,176 +0,0 @@ - -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Line dash generator -// -//---------------------------------------------------------------------------- -#include "../../../../include/fxcrt/fx_basic.h" -#include "agg_vcgen_dash.h" -#include "agg_shorten_path.h" -namespace agg -{ -vcgen_dash::vcgen_dash() : - m_total_dash_len(0), - m_num_dashes(0), - m_dash_start(0), - m_shorten(0), - m_curr_dash_start(0), - m_curr_dash(0), - m_src_vertices(), - m_closed(0), - m_status(initial), - m_src_vertex(0) -{ -} -void vcgen_dash::remove_all_dashes() -{ - m_total_dash_len = 0; - m_num_dashes = 0; - m_curr_dash_start = 0; - m_curr_dash = 0; -} -void vcgen_dash::add_dash(FX_FLOAT dash_len, FX_FLOAT gap_len) -{ - if(m_num_dashes < max_dashes) { - m_total_dash_len += dash_len + gap_len; - m_dashes[m_num_dashes++] = dash_len; - m_dashes[m_num_dashes++] = gap_len; - } -} -void vcgen_dash::dash_start(FX_FLOAT ds) -{ - m_dash_start = ds; - calc_dash_start(FXSYS_fabs(ds)); -} -void vcgen_dash::calc_dash_start(FX_FLOAT ds) -{ - m_curr_dash = 0; - m_curr_dash_start = 0; - while(ds > 0) { - if(ds > m_dashes[m_curr_dash]) { - ds -= m_dashes[m_curr_dash]; - ++m_curr_dash; - m_curr_dash_start = 0; - if(m_curr_dash >= m_num_dashes) { - m_curr_dash = 0; - } - } else { - m_curr_dash_start = ds; - ds = 0; - } - } -} -void vcgen_dash::remove_all() -{ - m_status = initial; - m_src_vertices.remove_all(); - m_closed = 0; -} -void vcgen_dash::add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd) -{ - m_status = initial; - if(is_move_to(cmd)) { - m_src_vertices.modify_last(vertex_dist(x, y)); - } else { - if(is_vertex(cmd)) { - m_src_vertices.add(vertex_dist(x, y)); - } else { - m_closed = get_close_flag(cmd); - } - } -} -void vcgen_dash::rewind(unsigned) -{ - if(m_status == initial) { - m_src_vertices.close(m_closed != 0); - shorten_path(m_src_vertices, m_shorten, m_closed); - } - m_status = ready; - m_src_vertex = 0; -} -unsigned vcgen_dash::vertex(FX_FLOAT* x, FX_FLOAT* y) -{ - unsigned cmd = path_cmd_move_to; - while(!is_stop(cmd)) { - switch(m_status) { - case initial: - rewind(0); - case ready: - if(m_num_dashes < 2 || m_src_vertices.size() < 2) { - cmd = path_cmd_stop; - break; - } - m_status = polyline; - m_src_vertex = 1; - m_v1 = &m_src_vertices[0]; - m_v2 = &m_src_vertices[1]; - m_curr_rest = m_v1->dist; - *x = m_v1->x; - *y = m_v1->y; - if(m_dash_start >= 0) { - calc_dash_start(m_dash_start); - } - return path_cmd_move_to; - case polyline: { - FX_FLOAT dash_rest = m_dashes[m_curr_dash] - m_curr_dash_start; - unsigned cmd = (m_curr_dash & 1) ? - path_cmd_move_to : - path_cmd_line_to; - if(m_curr_rest > dash_rest) { - m_curr_rest -= dash_rest; - ++m_curr_dash; - if(m_curr_dash >= m_num_dashes) { - m_curr_dash = 0; - } - m_curr_dash_start = 0; - *x = m_v2->x - (m_v2->x - m_v1->x) * m_curr_rest / m_v1->dist; - *y = m_v2->y - (m_v2->y - m_v1->y) * m_curr_rest / m_v1->dist; - } else { - m_curr_dash_start += m_curr_rest; - *x = m_v2->x; - *y = m_v2->y; - ++m_src_vertex; - m_v1 = m_v2; - m_curr_rest = m_v1->dist; - if(m_closed) { - if(m_src_vertex > m_src_vertices.size()) { - m_status = stop; - } else { - m_v2 = &m_src_vertices - [ - (m_src_vertex >= m_src_vertices.size()) ? 0 : - m_src_vertex - ]; - } - } else { - if(m_src_vertex >= m_src_vertices.size()) { - m_status = stop; - } else { - m_v2 = &m_src_vertices[m_src_vertex]; - } - } - } - return cmd; - } - break; - case stop: - cmd = path_cmd_stop; - break; - } - } - return path_cmd_stop; -} -} diff --git a/core/src/fxge/agg/agg23/fx_agg_vcgen_stroke.cpp b/core/src/fxge/agg/agg23/fx_agg_vcgen_stroke.cpp deleted file mode 100644 index 425ac45aca..0000000000 --- a/core/src/fxge/agg/agg23/fx_agg_vcgen_stroke.cpp +++ /dev/null @@ -1,214 +0,0 @@ - -//---------------------------------------------------------------------------- -// XYQ: 2006-01-22 Copied from AGG project. -// TODO: This file uses intensive floating point operations, so it's NOT suitable -// for platforms like Symbian OS. We need to change to FIX format. -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- -// 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. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Stroke generator -// -//---------------------------------------------------------------------------- -#include "../../../../include/fxcrt/fx_basic.h" -#include "agg_vcgen_stroke.h" -namespace agg -{ - -vcgen_stroke::vcgen_stroke() : - m_src_vertices(), - m_out_vertices(), - m_width(0.5f), - m_miter_limit(4 * 1.0f), - m_inner_miter_limit(1.0f + 1.0f / 100), - m_approx_scale(1.0f), - m_line_cap(butt_cap), - m_line_join(miter_join), - m_inner_join(inner_miter), - m_closed(0), - m_status(initial), - m_src_vertex(0), - m_out_vertex(0) -{ -} -void vcgen_stroke::remove_all() -{ - m_src_vertices.remove_all(); - m_closed = 0; - m_status = initial; -} -void vcgen_stroke::add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd) -{ - m_status = initial; - if(is_move_to(cmd)) { - m_src_vertices.modify_last(vertex_dist_cmd(x, y, cmd)); - } else { - if(is_vertex(cmd)) { - m_src_vertices.add(vertex_dist_cmd(x, y, cmd)); - } else { - m_closed = get_close_flag(cmd); - } - } -} -static inline void calc_butt_cap(FX_FLOAT* cap, - const vertex_dist& v0, - const vertex_dist& v1, - FX_FLOAT len, - FX_FLOAT width) -{ - FX_FLOAT dx = FXSYS_MulDiv(v1.y - v0.y, width, len); - FX_FLOAT dy = FXSYS_MulDiv(v1.x - v0.x, width, len); - cap[0] = v0.x - dx; - cap[1] = v0.y + dy; - cap[2] = v0.x + dx; - cap[3] = v0.y - dy; -} -void vcgen_stroke::rewind(unsigned) -{ - if(m_status == initial) { - m_src_vertices.close(m_closed != 0); - if(m_src_vertices.size() < 3) { - m_closed = 0; - } - } - m_status = ready; - m_src_vertex = 0; - m_out_vertex = 0; -} -unsigned vcgen_stroke::vertex(FX_FLOAT* x, FX_FLOAT* y) -{ - unsigned cmd = path_cmd_line_to; - line_join_e curj; - while(!is_stop(cmd)) { - switch(m_status) { - case initial: - rewind(0); - case ready: - if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) { - cmd = path_cmd_stop; - break; - } - m_status = m_closed ? outline1 : cap1; - cmd = path_cmd_move_to; - m_src_vertex = 0; - m_out_vertex = 0; - 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_src_vertex = 1; - m_prev_status = outline1; - m_status = out_vertices; - m_out_vertex = 0; - 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_prev_status = outline2; - m_status = out_vertices; - m_out_vertex = 0; - break; - case outline1: - if(m_closed) { - if(m_src_vertex >= m_src_vertices.size()) { - m_prev_status = close_first; - m_status = end_poly1; - break; - } - } else { - if(m_src_vertex >= m_src_vertices.size() - 1) { - m_status = cap2; - break; - } - } - curj = m_src_vertices[m_src_vertex].cmd & path_flags_jr ? miter_join_round : m_line_join; - 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, - curj, - m_inner_join, - m_miter_limit, - m_inner_miter_limit, - m_approx_scale); - ++m_src_vertex; - m_prev_status = m_status; - m_status = out_vertices; - m_out_vertex = 0; - break; - case close_first: - m_status = outline2; - cmd = path_cmd_move_to; - case outline2: - if(m_src_vertex <= unsigned(m_closed == 0)) { - m_status = end_poly2; - m_prev_status = stop; - break; - } - --m_src_vertex; - curj = m_src_vertices[m_src_vertex].cmd & path_flags_jr ? miter_join_round : m_line_join; - 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, - curj, - m_inner_join, - m_miter_limit, - m_inner_miter_limit, - m_approx_scale); - m_prev_status = m_status; - m_status = out_vertices; - m_out_vertex = 0; - break; - case out_vertices: - if(m_out_vertex >= m_out_vertices.size()) { - m_status = m_prev_status; - } else { - const point_type& c = m_out_vertices[m_out_vertex++]; - *x = c.x; - *y = c.y; - return cmd; - } - break; - case end_poly1: - m_status = m_prev_status; - return path_cmd_end_poly | path_flags_close | path_flags_ccw; - case end_poly2: - m_status = m_prev_status; - return path_cmd_end_poly | path_flags_close | path_flags_cw; - case stop: - cmd = path_cmd_stop; - break; - } - } - return cmd; -} -} diff --git a/core/src/fxge/agg/include/fx_agg_driver.h b/core/src/fxge/agg/include/fx_agg_driver.h index 803227e044..29b56c77e4 100644 --- a/core/src/fxge/agg/include/fx_agg_driver.h +++ b/core/src/fxge/agg/include/fx_agg_driver.h @@ -7,8 +7,9 @@ #ifndef FX_AGG_DRIVER_H_ #define FX_AGG_DRIVER_H_ -#include "fxfx_agg_path_storage.h" -#include "fxfx_agg_rasterizer_scanline_aa.h" +#include "../../../../../third_party/agg23/agg_clip_liang_barsky.h" +#include "../../../../../third_party/agg23/agg_path_storage.h" +#include "../../../../../third_party/agg23/agg_rasterizer_scanline_aa.h" class CAgg_PathData { diff --git a/core/src/fxge/agg/include/fxfx_agg_basics.h b/core/src/fxge/agg/include/fxfx_agg_basics.h deleted file mode 100644 index e27a843bba..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_basics.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_BASICS_H_ -#define FXFX_AGG_BASICS_H_ - -#include "../agg23/agg_basics.h" - -#endif // FXFX_AGG_BASICS_H_ diff --git a/core/src/fxge/agg/include/fxfx_agg_clip_liang_barsky.h b/core/src/fxge/agg/include/fxfx_agg_clip_liang_barsky.h deleted file mode 100644 index 2b64bf900a..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_clip_liang_barsky.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_CLIP_LIANG_BARSKY_H_ -#define FXFX_AGG_CLIP_LIANG_BARSKY_H_ - -#include "../agg23/agg_clip_liang_barsky.h" - -#endif // FXFX_AGG_CLIP_LIANG_BARSKY_H_ diff --git a/core/src/fxge/agg/include/fxfx_agg_conv_dash.h b/core/src/fxge/agg/include/fxfx_agg_conv_dash.h deleted file mode 100644 index fb1e42dae9..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_conv_dash.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_CONV_DASH_H_ -#define FXFX_AGG_CONV_DASH_H_ - -#include "../agg23/agg_conv_dash.h" - -#endif // FXFX_AGG_CONV_DASH_H_ diff --git a/core/src/fxge/agg/include/fxfx_agg_conv_stroke.h b/core/src/fxge/agg/include/fxfx_agg_conv_stroke.h deleted file mode 100644 index 531df5012e..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_conv_stroke.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_CONV_STROKE_H_ -#define FXFX_AGG_CONV_STROKE_H_ - -#include "../agg23/agg_conv_stroke.h" - -#endif // FXFX_AGG_CONV_STROKE_H_ diff --git a/core/src/fxge/agg/include/fxfx_agg_curves.h b/core/src/fxge/agg/include/fxfx_agg_curves.h deleted file mode 100644 index 1879958eca..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_curves.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_CURVES_H_ -#define FXFX_AGG_CURVES_H_ - -#include "../agg23/agg_curves.h" - -#endif // FXFX_AGG_CURVES_H_ diff --git a/core/src/fxge/agg/include/fxfx_agg_path_storage.h b/core/src/fxge/agg/include/fxfx_agg_path_storage.h deleted file mode 100644 index ab7a85bca5..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_path_storage.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_PATH_STORAGE_H_ -#define FXFX_AGG_PATH_STORAGE_H_ - -#include "../agg23/agg_path_storage.h" - -#endif // FXFX_AGG_PATH_STORAGE_H_ diff --git a/core/src/fxge/agg/include/fxfx_agg_rasterizer_scanline_aa.h b/core/src/fxge/agg/include/fxfx_agg_rasterizer_scanline_aa.h deleted file mode 100644 index a445298f81..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_rasterizer_scanline_aa.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_RASTERIZER_SCANLINE_AA_H_ -#define FXFX_AGG_RASTERIZER_SCANLINE_AA_H_ - -#include "../agg23/agg_rasterizer_scanline_aa.h" - -#endif // FXFX_AGG_RASTERIZER_SCANLINE_AA_H_ diff --git a/core/src/fxge/agg/include/fxfx_agg_renderer_scanline.h b/core/src/fxge/agg/include/fxfx_agg_renderer_scanline.h deleted file mode 100644 index 1775dabe3e..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_renderer_scanline.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_RENDER_SCANLINE_H_ -#define FXFX_AGG_RENDER_SCANLINE_H_ - -#include "../agg23/agg_renderer_scanline.h" - -#endif // FXFX_AGG_RENDER_SCANLINE_H_ diff --git a/core/src/fxge/agg/include/fxfx_agg_rendering_buffer.h b/core/src/fxge/agg/include/fxfx_agg_rendering_buffer.h deleted file mode 100644 index 0eb48b84c0..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_rendering_buffer.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_RENDERING_BUFFER_H_ -#define FXFX_AGG_RENDERING_BUFFER_H_ - -#include "../agg23/agg_rendering_buffer.h" - -#endif // FXFX_AGG_RENDERING_BUFFER_H_ diff --git a/core/src/fxge/agg/include/fxfx_agg_scanline_u.h b/core/src/fxge/agg/include/fxfx_agg_scanline_u.h deleted file mode 100644 index c850f621a3..0000000000 --- a/core/src/fxge/agg/include/fxfx_agg_scanline_u.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FXFX_AGG_SCANLINE_U_H_ -#define FXFX_AGG_SCANLINE_U_H_ - -#include "../agg23/agg_scanline_u.h" - -#endif // FXFX_AGG_SCANLINE_U_H_ diff --git a/core/src/fxge/agg/src/fx_agg_driver.cpp b/core/src/fxge/agg/src/fx_agg_driver.cpp new file mode 100644 index 0000000000..18a1fa43b5 --- /dev/null +++ b/core/src/fxge/agg/src/fx_agg_driver.cpp @@ -0,0 +1,1610 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../../include/fxge/fx_ge.h" +#include "../../dib/dib_int.h" +#include "../../ge/text_int.h" +#include "../../../../include/fxcodec/fx_codec.h" +#include "../../../../../third_party/agg23/agg_pixfmt_gray.h" +#include "../../../../../third_party/agg23/agg_path_storage.h" +#include "../../../../../third_party/agg23/agg_scanline_u.h" +#include "../../../../../third_party/agg23/agg_rasterizer_scanline_aa.h" +#include "../../../../../third_party/agg23/agg_renderer_scanline.h" +#include "../../../../../third_party/agg23/agg_curves.h" +#include "../../../../../third_party/agg23/agg_conv_stroke.h" +#include "../../../../../third_party/agg23/agg_conv_dash.h" +#include "../include/fx_agg_driver.h" +void _HardClip(FX_FLOAT& x, FX_FLOAT& y) +{ + if (x > 50000) { + x = 50000; + } + if (x < -50000) { + x = -50000; + } + if (y > 50000) { + y = 50000; + } + if (y < -50000) { + y = -50000; + } +} +void CAgg_PathData::BuildPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device) +{ + int nPoints = pPathData->GetPointCount(); + FX_PATHPOINT* pPoints = pPathData->GetPoints(); + for (int i = 0; i < nPoints; i ++) { + FX_FLOAT x = pPoints[i].m_PointX, y = pPoints[i].m_PointY; + if (pObject2Device) { + pObject2Device->Transform(x, y); + } + _HardClip(x, y); + int point_type = pPoints[i].m_Flag & FXPT_TYPE; + if (point_type == FXPT_MOVETO) { + m_PathData.move_to(x, y); + } else if (point_type == FXPT_LINETO) { + if (pPoints[i - 1].m_Flag == FXPT_MOVETO && (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && + pPoints[i].m_PointX == pPoints[i - 1].m_PointX && pPoints[i].m_PointY == pPoints[i - 1].m_PointY) { + x += 1; + } + m_PathData.line_to(x, y); + } else if (point_type == FXPT_BEZIERTO) { + FX_FLOAT x0 = pPoints[i - 1].m_PointX, y0 = pPoints[i - 1].m_PointY; + FX_FLOAT x2 = pPoints[i + 1].m_PointX, y2 = pPoints[i + 1].m_PointY; + FX_FLOAT x3 = pPoints[i + 2].m_PointX, y3 = pPoints[i + 2].m_PointY; + if (pObject2Device) { + pObject2Device->Transform(x0, y0); + pObject2Device->Transform(x2, y2); + pObject2Device->Transform(x3, y3); + } + agg::curve4 curve(x0, y0, x, y, x2, y2, x3, y3); + i += 2; + m_PathData.add_path_curve(curve); + } + if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) { + m_PathData.end_poly(); + } + } +} +namespace agg +{ +template class renderer_scanline_aa_offset +{ +public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + renderer_scanline_aa_offset(base_ren_type& ren, unsigned left, unsigned top) : + m_ren(&ren), m_left(left), m_top(top) + {} + void color(const color_type& c) + { + m_color = c; + } + const color_type& color() const + { + return m_color; + } + void prepare(unsigned) {} + template void render(const Scanline& sl) + { + int y = sl.y(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for(;;) { + int x = span->x; + if(span->len > 0) { + m_ren->blend_solid_hspan(x - m_left, y - m_top, (unsigned)span->len, + m_color, + span->covers); + } else { + m_ren->blend_hline(x - m_left, y - m_top, (unsigned)(x - span->len - 1), + m_color, + *(span->covers)); + } + if(--num_spans == 0) { + break; + } + ++span; + } + } +private: + base_ren_type* m_ren; + color_type m_color; + unsigned m_left, m_top; +}; +} +static void RasterizeStroke(agg::rasterizer_scanline_aa& rasterizer, agg::path_storage& path_data, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, FX_FLOAT scale = 1.0f, + FX_BOOL bStrokeAdjust = FALSE, FX_BOOL bTextMode = FALSE) +{ + agg::line_cap_e cap; + switch (pGraphState->m_LineCap) { + case CFX_GraphStateData::LineCapRound: + cap = agg::round_cap; + break; + case CFX_GraphStateData::LineCapSquare: + cap = agg::square_cap; + break; + default: + cap = agg::butt_cap; + break; + } + agg::line_join_e join; + switch (pGraphState->m_LineJoin) { + case CFX_GraphStateData::LineJoinRound: + join = agg::round_join; + break; + case CFX_GraphStateData::LineJoinBevel: + join = agg::bevel_join; + break; + default: + join = agg::miter_join_revert; + break; + } + FX_FLOAT width = pGraphState->m_LineWidth * scale; + FX_FLOAT unit = 1.f; + if (pObject2Device) { + unit = FXSYS_Div(1.0f, (pObject2Device->GetXUnit() + pObject2Device->GetYUnit()) / 2); + } + if (width < unit) { + width = unit; + } + if (pGraphState->m_DashArray == NULL) { + agg::conv_stroke stroke(path_data); + stroke.line_join(join); + stroke.line_cap(cap); + stroke.miter_limit(pGraphState->m_MiterLimit); + stroke.width(width); + rasterizer.add_path_transformed(stroke, pObject2Device); + } else { + typedef agg::conv_dash dash_converter; + dash_converter dash(path_data); + for (int i = 0; i < (pGraphState->m_DashCount + 1) / 2; i ++) { + FX_FLOAT on = pGraphState->m_DashArray[i * 2]; + if (on <= 0.000001f) { + on = 1.0f / 10; + } + FX_FLOAT off = i * 2 + 1 == pGraphState->m_DashCount ? on : + pGraphState->m_DashArray[i * 2 + 1]; + if (off < 0) { + off = 0; + } + dash.add_dash(on * scale, off * scale); + } + dash.dash_start(pGraphState->m_DashPhase * scale); + typedef agg::conv_stroke dash_stroke; + dash_stroke stroke(dash); + stroke.line_join(join); + stroke.line_cap(cap); + stroke.miter_limit(pGraphState->m_MiterLimit); + stroke.width(width); + rasterizer.add_path_transformed(stroke, pObject2Device); + } +} +IFX_RenderDeviceDriver* IFX_RenderDeviceDriver::CreateFxgeDriver(CFX_DIBitmap* pBitmap, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) +{ + return new CFX_AggDeviceDriver(pBitmap, 0, bRgbByteOrder, pOriDevice, bGroupKnockout); +} +CFX_AggDeviceDriver::CFX_AggDeviceDriver(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) +{ + m_pBitmap = pBitmap; + m_DitherBits = dither_bits; + m_pClipRgn = NULL; + m_pPlatformBitmap = NULL; + m_pPlatformGraphics = NULL; + m_pDwRenderTartget = NULL; + m_bRgbByteOrder = bRgbByteOrder; + m_pOriDevice = pOriDevice; + m_bGroupKnockout = bGroupKnockout; + m_FillFlags = 0; + InitPlatform(); +} +CFX_AggDeviceDriver::~CFX_AggDeviceDriver() +{ + if (m_pClipRgn) { + delete m_pClipRgn; + } + for (int i = 0; i < m_StateStack.GetSize(); i ++) + if (m_StateStack[i]) { + delete (CFX_ClipRgn*)m_StateStack[i]; + } + DestroyPlatform(); +} +#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ +void CFX_AggDeviceDriver::InitPlatform() +{ +} +void CFX_AggDeviceDriver::DestroyPlatform() +{ +} +FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, + CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color, + int alpha_flag, void* pIccTransform) +{ + return FALSE; +} +#endif +int CFX_AggDeviceDriver::GetDeviceCaps(int caps_id) +{ + switch (caps_id) { + case FXDC_DEVICE_CLASS: + return FXDC_DISPLAY; + case FXDC_PIXEL_WIDTH: + return m_pBitmap->GetWidth(); + case FXDC_PIXEL_HEIGHT: + return m_pBitmap->GetHeight(); + case FXDC_BITS_PIXEL: + return m_pBitmap->GetBPP(); + case FXDC_HORZ_SIZE: + case FXDC_VERT_SIZE: + return 0; + case FXDC_RENDER_CAPS: { + int flags = FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | FXRC_BLEND_MODE | FXRC_SOFT_CLIP; + if (m_pBitmap->HasAlpha()) { + flags |= FXRC_ALPHA_OUTPUT; + } else if (m_pBitmap->IsAlphaMask()) { + if (m_pBitmap->GetBPP() == 1) { + flags |= FXRC_BITMASK_OUTPUT; + } else { + flags |= FXRC_BYTEMASK_OUTPUT; + } + } + if (m_pBitmap->IsCmykImage()) { + flags |= FXRC_CMYK_OUTPUT; + } + return flags; + } + case FXDC_DITHER_BITS: + return m_DitherBits; + } + return 0; +} +void CFX_AggDeviceDriver::SaveState() +{ + void* pClip = NULL; + if (m_pClipRgn) { + pClip = new CFX_ClipRgn(*m_pClipRgn); + } + m_StateStack.Add(pClip); +} +void CFX_AggDeviceDriver::RestoreState(FX_BOOL bKeepSaved) +{ + if (m_StateStack.GetSize() == 0) { + if (m_pClipRgn) { + delete m_pClipRgn; + m_pClipRgn = NULL; + } + return; + } + CFX_ClipRgn* pSavedClip = (CFX_ClipRgn*)m_StateStack[m_StateStack.GetSize() - 1]; + if (m_pClipRgn) { + delete m_pClipRgn; + m_pClipRgn = NULL; + } + if (bKeepSaved) { + if (pSavedClip) { + m_pClipRgn = new CFX_ClipRgn(*pSavedClip); + } + } else { + m_StateStack.RemoveAt(m_StateStack.GetSize() - 1); + m_pClipRgn = pSavedClip; + } +} +void CFX_AggDeviceDriver::SetClipMask(agg::rasterizer_scanline_aa& rasterizer) +{ + FX_RECT path_rect(rasterizer.min_x(), rasterizer.min_y(), + rasterizer.max_x() + 1, rasterizer.max_y() + 1); + path_rect.Intersect(m_pClipRgn->GetBox()); + CFX_DIBitmapRef mask; + CFX_DIBitmap* pThisLayer = mask.New(); + if (!pThisLayer) { + return; + } + pThisLayer->Create(path_rect.Width(), path_rect.Height(), FXDIB_8bppMask); + pThisLayer->Clear(0); + agg::rendering_buffer raw_buf(pThisLayer->GetBuffer(), pThisLayer->GetWidth(), pThisLayer->GetHeight(), pThisLayer->GetPitch()); + agg::pixfmt_gray8 pixel_buf(raw_buf); + agg::renderer_base base_buf(pixel_buf); + agg::renderer_scanline_aa_offset > final_render(base_buf, path_rect.left, path_rect.top); + final_render.color(agg::gray8(255)); + agg::scanline_u8 scanline; + agg::render_scanlines(rasterizer, scanline, final_render, (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0); + m_pClipRgn->IntersectMaskF(path_rect.left, path_rect.top, mask); +} +FX_BOOL CFX_AggDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + int fill_mode + ) +{ + m_FillFlags = fill_mode; + if (m_pClipRgn == NULL) { + m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); + } + if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { + CFX_FloatRect rectf; + if (pPathData->IsRect(pObject2Device, &rectf)) { + rectf.Intersect(CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + FX_RECT rect = rectf.GetOutterRect(); + m_pClipRgn->IntersectRect(rect); + return TRUE; + } + } + CAgg_PathData path_data; + path_data.BuildPath(pPathData, pObject2Device); + path_data.m_PathData.end_poly(); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + rasterizer.add_path(path_data.m_PathData); + rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING ? agg::fill_non_zero : agg::fill_even_odd); + SetClipMask(rasterizer); + return TRUE; +} +FX_BOOL CFX_AggDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState + ) +{ + if (m_pClipRgn == NULL) { + m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); + } + CAgg_PathData path_data; + path_data.BuildPath(pPathData, NULL); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + RasterizeStroke(rasterizer, path_data.m_PathData, pObject2Device, pGraphState); + rasterizer.filling_rule(agg::fill_non_zero); + SetClipMask(rasterizer); + return TRUE; +} +class CFX_Renderer +{ +private: + int m_Alpha, + m_Red, + m_Green, + m_Blue, + m_Gray; + FX_DWORD m_Color; + FX_BOOL m_bFullCover; + FX_BOOL m_bRgbByteOrder; + CFX_DIBitmap* m_pOriDevice; + FX_RECT m_ClipBox; + const CFX_DIBitmap* m_pClipMask; + CFX_DIBitmap* m_pDevice; + const CFX_ClipRgn* m_pClipRgn; + void (CFX_Renderer::*composite_span)(uint8_t*, int, int, int, uint8_t*, int, int, uint8_t*, uint8_t*); +public: + void prepare(unsigned) {} + void CompositeSpan(uint8_t* dest_scan, uint8_t* ori_scan, int Bpp, FX_BOOL bDestAlpha, + int span_left, int span_len, uint8_t* cover_scan, + int clip_left, int clip_right, uint8_t* clip_scan) + { + ASSERT(!m_pDevice->IsCmykImage()); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (Bpp) { + dest_scan += col_start * Bpp; + ori_scan += col_start * Bpp; + } else { + dest_scan += col_start / 8; + ori_scan += col_start / 8; + } + if (m_bRgbByteOrder) { + if (Bpp == 4 && bDestAlpha) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + uint8_t dest_alpha = ori_scan[3] + src_alpha - ori_scan[3] * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (m_bFullCover) { + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio); + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio); + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio); + dest_scan++; + ori_scan++; + } else { + int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio); + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio); + ori_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, r, cover_scan[col]); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]); + dest_scan += 2; + } + } + return; + } else if (Bpp == 3 || Bpp == 4) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255 ; + } else { + src_alpha = m_Alpha; + } + int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + int b = FXDIB_ALPHA_MERGE(*ori_scan, m_Blue, src_alpha); + ori_scan += Bpp - 2; + *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, r, cover_scan[col]); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]); + dest_scan += Bpp - 2; + } + } + return; + } + if (Bpp == 4 && bDestAlpha) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + int src_alpha_covered = src_alpha * cover_scan[col] / 255; + if (src_alpha_covered == 0) { + dest_scan += 4; + continue; + } + if (cover_scan[col] == 255) { + dest_scan[3] = src_alpha_covered; + *dest_scan ++ = m_Blue; + *dest_scan ++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; + } else { + if (dest_scan[3] == 0) { + dest_scan[3] = src_alpha_covered; + *dest_scan ++ = m_Blue; + *dest_scan ++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; + } + uint8_t cover = cover_scan[col]; + dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover); + dest_scan += 2; + } + } + return; + } else if (Bpp == 3 || Bpp == 4) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + if (m_bFullCover) { + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); + dest_scan += Bpp - 2; + ori_scan += Bpp - 2; + continue; + } + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); + ori_scan += Bpp - 2; + *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, b, cover_scan[col]); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]); + dest_scan += Bpp - 2; + continue; + } + return; + } else if (Bpp == 1) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + if (m_bFullCover) { + *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); + } else { + int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan[col]); + dest_scan++; + } + } + } else { + int index = 0; + if (m_pDevice->GetPalette() == NULL) { + index = ((uint8_t)m_Color == 0xff) ? 1 : 0; + } else { + for (int i = 0; i < 2; i ++) + if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) { + index = i; + } + } + uint8_t* dest_scan1 = dest_scan; + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + if (src_alpha) { + if (!index) { + *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); + } else { + *dest_scan1 |= 1 << (7 - (col + span_left) % 8); + } + } + dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; + } + } + } + void CompositeSpan1bpp(uint8_t* dest_scan, int Bpp, + int span_left, int span_len, uint8_t* cover_scan, + int clip_left, int clip_right, uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) + { + ASSERT(!m_bRgbByteOrder); + ASSERT(!m_pDevice->IsCmykImage()); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + dest_scan += col_start / 8; + int index = 0; + if (m_pDevice->GetPalette() == NULL) { + index = ((uint8_t)m_Color == 0xff) ? 1 : 0; + } else { + for (int i = 0; i < 2; i ++) + if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) { + index = i; + } + } + uint8_t* dest_scan1 = dest_scan; + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + if (src_alpha) { + if (!index) { + *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); + } else { + *dest_scan1 |= 1 << (7 - (col + span_left) % 8); + } + } + dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; + } + } + void CompositeSpanGray(uint8_t* dest_scan, int Bpp, + int span_left, int span_len, uint8_t* cover_scan, + int clip_left, int clip_right, uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) + { + ASSERT(!m_bRgbByteOrder); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + dest_scan += col_start; + if (dest_extra_alpha_scan) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + } else { + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + } + if (src_alpha) { + if (src_alpha == 255) { + *dest_scan = m_Gray; + *dest_extra_alpha_scan = m_Alpha; + } else { + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); + dest_scan ++; + continue; + } + } + dest_extra_alpha_scan ++; + dest_scan ++; + } + } else { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + if (src_alpha) { + if (src_alpha == 255) { + *dest_scan = m_Gray; + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); + } + } + dest_scan ++; + } + } + } + void CompositeSpanARGB(uint8_t* dest_scan, int Bpp, + int span_left, int span_len, uint8_t* cover_scan, + int clip_left, int clip_right, uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) + { + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + dest_scan += col_start * Bpp; + if (m_bRgbByteOrder) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + } else { + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + } + if (src_alpha) { + if (src_alpha == 255) { + *(FX_DWORD*)dest_scan = m_Color; + } else { + uint8_t dest_alpha = dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan += 2; + continue; + } + } + dest_scan += 4; + } + return; + } + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + } else { + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + } + if (src_alpha) { + if (src_alpha == 255) { + *(FX_DWORD*)dest_scan = m_Color; + } else { + if (dest_scan[3] == 0) { + dest_scan[3] = src_alpha; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; + } + uint8_t dest_alpha = dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan += 2; + continue; + } + } + dest_scan += Bpp; + } + } + void CompositeSpanRGB(uint8_t* dest_scan, int Bpp, + int span_left, int span_len, uint8_t* cover_scan, + int clip_left, int clip_right, uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) + { + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + dest_scan += col_start * Bpp; + if (m_bRgbByteOrder) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + if (src_alpha) { + if (src_alpha == 255) { + if (Bpp == 4) { + *(FX_DWORD*)dest_scan = m_Color; + } else if (Bpp == 3) { + *dest_scan++ = m_Red; + *dest_scan++ = m_Green; + *dest_scan++ = m_Blue; + continue; + } + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan += Bpp - 2; + continue; + } + } + dest_scan += Bpp; + } + return; + } + if (Bpp == 3 && dest_extra_alpha_scan) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + } else { + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + } + if (src_alpha) { + if (src_alpha == 255) { + *dest_scan++ = (uint8_t)m_Blue; + *dest_scan++ = (uint8_t)m_Green; + *dest_scan++ = (uint8_t)m_Red; + *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; + continue; + } else { + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan ++; + continue; + } + } + dest_extra_alpha_scan++; + dest_scan += Bpp; + } + } else { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + } else { + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + } + if (src_alpha) { + if (src_alpha == 255) { + if (Bpp == 4) { + *(FX_DWORD*)dest_scan = m_Color; + } else if (Bpp == 3) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; + continue; + } + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan += Bpp - 2; + continue; + } + } + dest_scan += Bpp; + } + } + } + void CompositeSpanCMYK(uint8_t* dest_scan, int Bpp, + int span_left, int span_len, uint8_t* cover_scan, + int clip_left, int clip_right, uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) + { + ASSERT(!m_bRgbByteOrder); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + dest_scan += col_start * 4; + if (dest_extra_alpha_scan) { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + } else { + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + } + if (src_alpha) { + if (src_alpha == 255) { + *(FX_CMYK*)dest_scan = m_Color; + *dest_extra_alpha_scan = (uint8_t)m_Alpha; + } else { + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); + dest_scan ++; + continue; + } + } + dest_extra_alpha_scan++; + dest_scan += 4; + } + } else { + for (int col = col_start; col < col_end; col ++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + if (src_alpha) { + if (src_alpha == 255) { + *(FX_CMYK*)dest_scan = m_Color; + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan ++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); + dest_scan ++; + continue; + } + } + dest_scan += 4; + } + } + } + template void render(const Scanline& sl) + { + if (m_pOriDevice == NULL && composite_span == NULL) { + return; + } + int y = sl.y(); + if (y < m_ClipBox.top || y >= m_ClipBox.bottom) { + return; + } + uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * y; + uint8_t* dest_scan_extra_alpha = NULL; + CFX_DIBitmap* pAlphaMask = m_pDevice->m_pAlphaMask; + if (pAlphaMask) { + dest_scan_extra_alpha = pAlphaMask->GetBuffer() + pAlphaMask->GetPitch() * y; + } + uint8_t* ori_scan = NULL; + if (m_pOriDevice) { + ori_scan = m_pOriDevice->GetBuffer() + m_pOriDevice->GetPitch() * y; + } + int Bpp = m_pDevice->GetBPP() / 8; + FX_BOOL bDestAlpha = m_pDevice->HasAlpha() || m_pDevice->IsAlphaMask(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + while (1) { + int x = span->x; + ASSERT(span->len > 0); + uint8_t* dest_pos = NULL; + uint8_t* dest_extra_alpha_pos = NULL; + uint8_t* ori_pos = NULL; + if (Bpp) { + ori_pos = ori_scan ? ori_scan + x * Bpp : NULL; + dest_pos = dest_scan + x * Bpp; + dest_extra_alpha_pos = dest_scan_extra_alpha ? dest_scan_extra_alpha + x : NULL; + } else { + dest_pos = dest_scan + x / 8; + ori_pos = ori_scan ? ori_scan + x / 8 : NULL; + } + uint8_t* clip_pos = NULL; + if (m_pClipMask) { + clip_pos = m_pClipMask->GetBuffer() + (y - m_ClipBox.top) * m_pClipMask->GetPitch() + x - m_ClipBox.left; + } + if (ori_pos) { + CompositeSpan(dest_pos, ori_pos, Bpp, bDestAlpha, x, span->len, span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos); + } else { + (this->*composite_span)(dest_pos, Bpp, x, span->len, span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos, dest_extra_alpha_pos); + } + if(--num_spans == 0) { + break; + } + ++span; + } + } + + FX_BOOL Init(CFX_DIBitmap* pDevice, CFX_DIBitmap* pOriDevice, const CFX_ClipRgn* pClipRgn, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bRgbByteOrder, + int alpha_flag = 0, void* pIccTransform = NULL) + { + m_pDevice = pDevice; + m_pClipRgn = pClipRgn; + composite_span = NULL; + m_bRgbByteOrder = bRgbByteOrder; + m_pOriDevice = pOriDevice; + if (m_pClipRgn) { + m_ClipBox = m_pClipRgn->GetBox(); + } else { + m_ClipBox.left = m_ClipBox.top = 0; + m_ClipBox.right = m_pDevice->GetWidth(); + m_ClipBox.bottom = m_pDevice->GetHeight(); + } + m_pClipMask = NULL; + if (m_pClipRgn && m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { + m_pClipMask = m_pClipRgn->GetMask(); + } + m_bFullCover = bFullCover; + FX_BOOL bObjectCMYK = FXGETFLAG_COLORTYPE(alpha_flag); + FX_BOOL bDeviceCMYK = pDevice->IsCmykImage(); + m_Alpha = bObjectCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); + ICodec_IccModule* pIccModule = NULL; + if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + pIccTransform = NULL; + } else { + pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + } + if (m_pDevice->GetBPP() == 8) { + ASSERT(!m_bRgbByteOrder); + composite_span = &CFX_Renderer::CompositeSpanGray; + if (m_pDevice->IsAlphaMask()) { + m_Gray = 255; + } else { + if (pIccTransform) { + uint8_t gray; + color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, &gray, (const uint8_t*)&color, 1); + m_Gray = gray; + } else { + if (bObjectCMYK) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), + r, g, b); + m_Gray = FXRGB2GRAY(r, g, b); + } else { + m_Gray = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); + } + } + } + return TRUE; + } + if (bDeviceCMYK) { + ASSERT(!m_bRgbByteOrder); + composite_span = &CFX_Renderer::CompositeSpanCMYK; + if (bObjectCMYK) { + m_Color = FXCMYK_TODIB(color); + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&m_Color, 1); + } + } else { + if (!pIccTransform) { + return FALSE; + } + color = FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&color, 1); + } + m_Red = ((uint8_t*)&m_Color)[0]; + m_Green = ((uint8_t*)&m_Color)[1]; + m_Blue = ((uint8_t*)&m_Color)[2]; + m_Gray = ((uint8_t*)&m_Color)[3]; + } else { + composite_span = (pDevice->GetFormat() == FXDIB_Argb) ? &CFX_Renderer::CompositeSpanARGB : &CFX_Renderer::CompositeSpanRGB; + if (pIccTransform) { + color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&color, 1); + ((uint8_t*)&m_Color)[3] = m_Alpha; + m_Red = ((uint8_t*)&m_Color)[2]; + m_Green = ((uint8_t*)&m_Color)[1]; + m_Blue = ((uint8_t*)&m_Color)[0]; + if (m_bRgbByteOrder) { + m_Color = FXARGB_TODIB(m_Color); + m_Color = FXARGB_TOBGRORDERDIB(m_Color); + } + } else { + if (bObjectCMYK) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), + r, g, b); + m_Color = FXARGB_MAKE(m_Alpha, r, g, b); + if (m_bRgbByteOrder) { + m_Color = FXARGB_TOBGRORDERDIB(m_Color); + } else { + m_Color = FXARGB_TODIB(m_Color); + } + m_Red = r; + m_Green = g; + m_Blue = b; + } else { + if (m_bRgbByteOrder) { + m_Color = FXARGB_TOBGRORDERDIB(color); + } else { + m_Color = FXARGB_TODIB(color); + } + ArgbDecode(color, m_Alpha, m_Red, m_Green, m_Blue); + } + } + } + if (m_pDevice->GetBPP() == 1) { + composite_span = &CFX_Renderer::CompositeSpan1bpp; + } + return TRUE; + } +}; +FX_BOOL CFX_AggDeviceDriver::RenderRasterizer(agg::rasterizer_scanline_aa& rasterizer, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bGroupKnockout, + int alpha_flag, void* pIccTransform) +{ + CFX_DIBitmap* pt = bGroupKnockout ? m_pOriDevice : NULL; + CFX_Renderer render; + if (!render.Init(m_pBitmap, pt, m_pClipRgn, color, bFullCover, m_bRgbByteOrder, alpha_flag, pIccTransform)) { + return FALSE; + } + agg::scanline_u8 scanline; + agg::render_scanlines(rasterizer, scanline, render, (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0); + return TRUE; +} +FX_BOOL CFX_AggDeviceDriver::DrawPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + FX_DWORD fill_color, + FX_DWORD stroke_color, + int fill_mode, + int alpha_flag, + void* pIccTransform, + int blend_type + ) +{ + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + if (GetBuffer() == NULL) { + return TRUE; + } + m_FillFlags = fill_mode; + if ((fill_mode & 3) && fill_color) { + CAgg_PathData path_data; + path_data.BuildPath(pPathData, pObject2Device); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + rasterizer.add_path(path_data.m_PathData); + rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING ? agg::fill_non_zero : agg::fill_even_odd); + if (!RenderRasterizer(rasterizer, fill_color, fill_mode & FXFILL_FULLCOVER, FALSE, alpha_flag, pIccTransform)) { + return FALSE; + } + } + int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_STROKE(alpha_flag) : FXARGB_A(stroke_color); + if (pGraphState && stroke_alpha) { + if (fill_mode & FX_ZEROAREA_FILL) { + CAgg_PathData path_data; + path_data.BuildPath(pPathData, pObject2Device); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + RasterizeStroke(rasterizer, path_data.m_PathData, NULL, pGraphState, 1, FALSE, fill_mode & FX_STROKE_TEXT_MODE); + int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 | FXGETFLAG_ALPHA_STROKE(alpha_flag); + if (!RenderRasterizer(rasterizer, stroke_color, fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout, fill_flag, pIccTransform)) { + return FALSE; + } + return TRUE; + } + CFX_AffineMatrix matrix1, matrix2; + if (pObject2Device) { + matrix1.a = FX_MAX(FXSYS_fabs(pObject2Device->a), FXSYS_fabs(pObject2Device->b)); + matrix1.d = matrix1.a; + matrix2.Set(pObject2Device->a / matrix1.a, pObject2Device->b / matrix1.a, + pObject2Device->c / matrix1.d, pObject2Device->d / matrix1.d, + 0, 0); + CFX_AffineMatrix mtRervese; + mtRervese.SetReverse(matrix2); + matrix1 = *pObject2Device; + matrix1.Concat(mtRervese); + } + CAgg_PathData path_data; + path_data.BuildPath(pPathData, &matrix1); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + RasterizeStroke(rasterizer, path_data.m_PathData, &matrix2, pGraphState, matrix1.a, FALSE, fill_mode & FX_STROKE_TEXT_MODE); + int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 | FXGETFLAG_ALPHA_STROKE(alpha_flag); + if (!RenderRasterizer(rasterizer, stroke_color, fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout, fill_flag, pIccTransform)) { + return FALSE; + } + } + return TRUE; +} +void RgbByteOrderSetPixel(CFX_DIBitmap* pBitmap, int x, int y, FX_DWORD argb) +{ + if (x < 0 || x >= pBitmap->GetWidth() || y < 0 || y >= pBitmap->GetHeight()) { + return; + } + uint8_t* pos = (uint8_t*)pBitmap->GetBuffer() + y * pBitmap->GetPitch() + x * pBitmap->GetBPP() / 8; + if (pBitmap->GetFormat() == FXDIB_Argb) { + FXARGB_SETRGBORDERDIB(pos, ArgbGamma(argb)); + } else { + int alpha = FXARGB_A(argb); + pos[0] = (FXARGB_R(argb) * alpha + pos[0] * (255 - alpha)) / 255; + pos[1] = (FXARGB_G(argb) * alpha + pos[1] * (255 - alpha)) / 255; + pos[2] = (FXARGB_B(argb) * alpha + pos[2] * (255 - alpha)) / 255; + } +} +void RgbByteOrderCompositeRect(CFX_DIBitmap* pBitmap, int left, int top, int width, int height, FX_ARGB argb) +{ + int src_alpha = FXARGB_A(argb); + if (src_alpha == 0) { + return; + } + FX_RECT rect(left, top, left + width, top + height); + rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); + width = rect.Width(); + int src_r = FXARGB_R(argb), src_g = FXARGB_G(argb), src_b = FXARGB_B(argb); + int Bpp = pBitmap->GetBPP() / 8; + FX_BOOL bAlpha = pBitmap->HasAlpha(); + int dib_argb = FXARGB_TOBGRORDERDIB(argb); + uint8_t* pBuffer = pBitmap->GetBuffer(); + if (src_alpha == 255) { + for (int row = rect.top; row < rect.bottom; row ++) { + uint8_t* dest_scan = pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp; + if (Bpp == 4) { + FX_DWORD* scan = (FX_DWORD*)dest_scan; + for (int col = 0; col < width; col ++) { + *scan ++ = dib_argb; + } + } else { + for (int col = 0; col < width; col ++) { + *dest_scan ++ = src_r; + *dest_scan ++ = src_g; + *dest_scan ++ = src_b; + } + } + } + return; + } + src_r = FX_GAMMA(src_r); + src_g = FX_GAMMA(src_g); + src_b = FX_GAMMA(src_b); + for (int row = rect.top; row < rect.bottom; row ++) { + uint8_t* dest_scan = pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp; + if (bAlpha) { + for (int col = 0; col < width; col ++) { + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); + dest_scan += 4; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan += 2; + } + } else { + for (int col = 0; col < width; col ++) { + *dest_scan = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_r, src_alpha)); + dest_scan++; + *dest_scan = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_g, src_alpha)); + dest_scan++; + *dest_scan = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_b, src_alpha)); + dest_scan++; + if (Bpp == 4) { + dest_scan++; + } + } + } + } +} +void RgbByteOrderTransferBitmap(CFX_DIBitmap* pBitmap, int dest_left, int dest_top, int width, int height, + const CFX_DIBSource* pSrcBitmap, int src_left, int src_top) +{ + if (pBitmap == NULL) { + return; + } + pBitmap->GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), src_left, src_top, NULL); + if (width == 0 || height == 0) { + return; + } + int Bpp = pBitmap->GetBPP() / 8; + FXDIB_Format dest_format = pBitmap->GetFormat(); + FXDIB_Format src_format = pSrcBitmap->GetFormat(); + int pitch = pBitmap->GetPitch(); + uint8_t* buffer = pBitmap->GetBuffer(); + if (dest_format == src_format) { + for (int row = 0; row < height; row ++) { + uint8_t* dest_scan = buffer + (dest_top + row) * pitch + dest_left * Bpp; + uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; + if (Bpp == 4) { + for (int col = 0; col < width; col ++) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_scan[3], src_scan[0], src_scan[1], src_scan[2])); + dest_scan += 4; + src_scan += 4; + } + } else { + for (int col = 0; col < width; col ++) { + *dest_scan++ = src_scan[2]; + *dest_scan++ = src_scan[1]; + *dest_scan++ = src_scan[0]; + src_scan += 3; + } + } + } + return; + } + uint8_t* dest_buf = buffer + dest_top * pitch + dest_left * Bpp; + if (dest_format == FXDIB_Rgb) { + if (src_format == FXDIB_Rgb32) { + for (int row = 0; row < height; row ++) { + uint8_t* dest_scan = dest_buf + row * pitch; + uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 4; + for (int col = 0; col < width; col ++) { + *dest_scan++ = src_scan[2]; + *dest_scan++ = src_scan[1]; + *dest_scan++ = src_scan[0]; + src_scan += 4; + } + } + } else { + ASSERT(FALSE); + } + } else if (dest_format == FXDIB_Argb || dest_format == FXDIB_Rgb32) { + if (src_format == FXDIB_Rgb) { + for (int row = 0; row < height; row ++) { + uint8_t* dest_scan = (uint8_t*)(dest_buf + row * pitch); + uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 3; + if (src_format == FXDIB_Argb) { + for (int col = 0; col < width; col ++) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, FX_GAMMA(src_scan[0]), FX_GAMMA(src_scan[1]), FX_GAMMA(src_scan[2]))); + dest_scan += 4; + src_scan += 3; + } + } else { + for (int col = 0; col < width; col ++) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1], src_scan[2])); + dest_scan += 4; + src_scan += 3; + } + } + } + } else if (src_format == FXDIB_Rgb32) { + ASSERT(dest_format == FXDIB_Argb); + for (int row = 0; row < height; row ++) { + uint8_t* dest_scan = dest_buf + row * pitch; + uint8_t* src_scan = (uint8_t*)(pSrcBitmap->GetScanline(src_top + row) + src_left * 4); + for (int col = 0; col < width; col++) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1], src_scan[2])); + src_scan += 4; + dest_scan += 4; + } + } + } + } else { + ASSERT(FALSE); + } +} +FX_ARGB _DefaultCMYK2ARGB(FX_CMYK cmyk, uint8_t alpha) +{ + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), + r, g, b); + return ArgbEncode(alpha, r, g, b); +} +FX_BOOL _DibSetPixel(CFX_DIBitmap* pDevice, int x, int y, FX_DWORD color, int alpha_flag, void* pIccTransform) +{ + FX_BOOL bObjCMYK = FXGETFLAG_COLORTYPE(alpha_flag); + int alpha = bObjCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); + if (pIccTransform) { + ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&color, (uint8_t*)&color, 1); + color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + if (!pDevice->IsCmykImage()) { + color = (color & 0xffffff) | (alpha << 24); + } + } else { + if (pDevice->IsCmykImage()) { + if (!bObjCMYK) { + return FALSE; + } + } else { + if (bObjCMYK) { + color = _DefaultCMYK2ARGB(color, alpha); + } + } + } + pDevice->SetPixel(x, y, color); + if (pDevice->m_pAlphaMask) { + pDevice->m_pAlphaMask->SetPixel(x, y, alpha << 24); + } + return TRUE; +} +FX_BOOL CFX_AggDeviceDriver::SetPixel(int x, int y, FX_DWORD color, int alpha_flag, void* pIccTransform) +{ + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + pIccTransform = NULL; + } + if (m_pClipRgn == NULL) { + if (m_bRgbByteOrder) { + RgbByteOrderSetPixel(m_pBitmap, x, y, color); + } else { + return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); + } + } else if (m_pClipRgn->GetBox().Contains(x, y)) { + if (m_pClipRgn->GetType() == CFX_ClipRgn::RectI) { + if (m_bRgbByteOrder) { + RgbByteOrderSetPixel(m_pBitmap, x, y, color); + } else { + return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); + } + } else if (m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { + const CFX_DIBitmap* pMask = m_pClipRgn->GetMask(); + FX_BOOL bCMYK = FXGETFLAG_COLORTYPE(alpha_flag); + int new_alpha = bCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); + new_alpha = new_alpha * pMask->GetScanline(y)[x] / 255; + if (m_bRgbByteOrder) { + RgbByteOrderSetPixel(m_pBitmap, x, y, (color & 0xffffff) | (new_alpha << 24)); + return TRUE; + } + if (bCMYK) { + FXSETFLAG_ALPHA_FILL(alpha_flag, new_alpha); + } else { + color = (color & 0xffffff) | (new_alpha << 24); + } + return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); + } + } + return TRUE; +} +FX_BOOL CFX_AggDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type) +{ + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + FX_RECT clip_rect; + GetClipBox(&clip_rect); + FX_RECT draw_rect = clip_rect; + if (pRect) { + draw_rect.Intersect(*pRect); + } + if (draw_rect.IsEmpty()) { + return TRUE; + } + if (m_pClipRgn == NULL || m_pClipRgn->GetType() == CFX_ClipRgn::RectI) { + if (m_bRgbByteOrder) { + RgbByteOrderCompositeRect(m_pBitmap, draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), fill_color); + } else { + m_pBitmap->CompositeRect(draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), fill_color, alpha_flag, pIccTransform); + } + return TRUE; + } + m_pBitmap->CompositeMask(draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), (const CFX_DIBitmap*)m_pClipRgn->GetMask(), + fill_color, draw_rect.left - clip_rect.left, draw_rect.top - clip_rect.top, FXDIB_BLEND_NORMAL, NULL, m_bRgbByteOrder, alpha_flag, pIccTransform); + return TRUE; +} +FX_BOOL CFX_AggDeviceDriver::GetClipBox(FX_RECT* pRect) +{ + if (m_pClipRgn == NULL) { + pRect->left = pRect->top = 0; + pRect->right = GetDeviceCaps(FXDC_PIXEL_WIDTH); + pRect->bottom = GetDeviceCaps(FXDC_PIXEL_HEIGHT); + return TRUE; + } + *pRect = m_pClipRgn->GetBox(); + return TRUE; +} +FX_BOOL CFX_AggDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform, FX_BOOL bDEdge) +{ + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + if (bDEdge) { + if (m_bRgbByteOrder) { + RgbByteOrderTransferBitmap(pBitmap, 0, 0, pBitmap->GetWidth(), pBitmap->GetHeight(), m_pBitmap, left, top); + } else { + return pBitmap->TransferBitmap(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight(), m_pBitmap, left, top, pIccTransform); + } + return TRUE; + } + FX_RECT rect(left, top, left + pBitmap->GetWidth(), top + pBitmap->GetHeight()); + CFX_DIBitmap *pBack = NULL; + if (m_pOriDevice) { + pBack = m_pOriDevice->Clone(&rect); + if (!pBack) { + return TRUE; + } + pBack->CompositeBitmap(0, 0, pBack->GetWidth(), pBack->GetHeight(), m_pBitmap, 0, 0); + } else { + pBack = m_pBitmap->Clone(&rect); + } + if (!pBack) { + return TRUE; + } + FX_BOOL bRet = TRUE; + left = left >= 0 ? 0 : left; + top = top >= 0 ? 0 : top; + if (m_bRgbByteOrder) { + RgbByteOrderTransferBitmap(pBitmap, 0, 0, rect.Width(), rect.Height(), pBack, left, top); + } else { + bRet = pBitmap->TransferBitmap(0, 0, rect.Width(), rect.Height(), pBack, left, top, pIccTransform); + } + delete pBack; + return bRet; +} +FX_BOOL CFX_AggDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD argb, const FX_RECT* pSrcRect, int left, int top, int blend_type, + int alpha_flag, void* pIccTransform) +{ + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + if (pBitmap->IsAlphaMask()) + return m_pBitmap->CompositeMask(left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, argb, + pSrcRect->left, pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder, alpha_flag, pIccTransform); + return m_pBitmap->CompositeBitmap(left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, + pSrcRect->left, pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder, pIccTransform); +} +FX_BOOL CFX_AggDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD argb, int dest_left, int dest_top, + int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, + int alpha_flag, void* pIccTransform, int blend_type) +{ + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + if (dest_width == pSource->GetWidth() && dest_height == pSource->GetHeight()) { + FX_RECT rect(0, 0, dest_width, dest_height); + return SetDIBits(pSource, argb, &rect, dest_left, dest_top, blend_type, alpha_flag, pIccTransform); + } + FX_RECT dest_rect(dest_left, dest_top, dest_left + dest_width, dest_top + dest_height); + dest_rect.Normalize(); + FX_RECT dest_clip = dest_rect; + dest_clip.Intersect(*pClipRect); + CFX_BitmapComposer composer; + composer.Compose(m_pBitmap, m_pClipRgn, 255, argb, dest_clip, FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_flag, pIccTransform, blend_type); + dest_clip.Offset(-dest_rect.left, -dest_rect.top); + CFX_ImageStretcher stretcher; + if (stretcher.Start(&composer, pSource, dest_width, dest_height, dest_clip, flags)) { + stretcher.Continue(NULL); + } + return TRUE; +} +FX_BOOL CFX_AggDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_alpha, FX_DWORD argb, + const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, void*& handle, + int alpha_flag, void* pIccTransform, int blend_type) +{ + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + CFX_ImageRenderer* pRenderer = new CFX_ImageRenderer; + pRenderer->Start(m_pBitmap, m_pClipRgn, pSource, bitmap_alpha, argb, pMatrix, render_flags, m_bRgbByteOrder, alpha_flag, pIccTransform); + handle = pRenderer; + return TRUE; +} +FX_BOOL CFX_AggDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) +{ + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + return ((CFX_ImageRenderer*)pHandle)->Continue(pPause); +} +void CFX_AggDeviceDriver::CancelDIBits(void* pHandle) +{ + if (m_pBitmap->GetBuffer() == NULL) { + return; + } + delete (CFX_ImageRenderer*)pHandle; +} +CFX_FxgeDevice::CFX_FxgeDevice() +{ + m_bOwnedBitmap = FALSE; +} +FX_BOOL CFX_FxgeDevice::Attach(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) +{ + if (pBitmap == NULL) { + return FALSE; + } + SetBitmap(pBitmap); + IFX_RenderDeviceDriver* pDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); + SetDeviceDriver(pDriver); + return TRUE; +} +FX_BOOL CFX_FxgeDevice::Create(int width, int height, FXDIB_Format format, int dither_bits, CFX_DIBitmap* pOriDevice) +{ + m_bOwnedBitmap = TRUE; + CFX_DIBitmap* pBitmap = new CFX_DIBitmap; + if (!pBitmap->Create(width, height, format)) { + delete pBitmap; + return FALSE; + } + SetBitmap(pBitmap); + IFX_RenderDeviceDriver* pDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, FALSE, pOriDevice, FALSE); + SetDeviceDriver(pDriver); + return TRUE; +} +CFX_FxgeDevice::~CFX_FxgeDevice() +{ + if (m_bOwnedBitmap && GetBitmap()) { + delete GetBitmap(); + } +} diff --git a/core/src/fxge/agg/src/fxfx_agg_curves.cpp b/core/src/fxge/agg/src/fxfx_agg_curves.cpp deleted file mode 100644 index 83817f7680..0000000000 --- a/core/src/fxge/agg/src/fxfx_agg_curves.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "../agg23/fx_agg_curves.cpp" diff --git a/core/src/fxge/agg/src/fxfx_agg_driver.cpp b/core/src/fxge/agg/src/fxfx_agg_driver.cpp deleted file mode 100644 index a4e6a30d44..0000000000 --- a/core/src/fxge/agg/src/fxfx_agg_driver.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "../agg23/fx_agg_driver.cpp" diff --git a/core/src/fxge/agg/src/fxfx_agg_path_storage.cpp b/core/src/fxge/agg/src/fxfx_agg_path_storage.cpp deleted file mode 100644 index fabc526a24..0000000000 --- a/core/src/fxge/agg/src/fxfx_agg_path_storage.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "../agg23/fx_agg_path_storage.cpp" diff --git a/core/src/fxge/agg/src/fxfx_agg_rasterizer_scanline_aa.cpp b/core/src/fxge/agg/src/fxfx_agg_rasterizer_scanline_aa.cpp deleted file mode 100644 index 229e3ba93a..0000000000 --- a/core/src/fxge/agg/src/fxfx_agg_rasterizer_scanline_aa.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "../agg23/fx_agg_rasterizer_scanline_aa.cpp" diff --git a/core/src/fxge/agg/src/fxfx_agg_vcgen_dash.cpp b/core/src/fxge/agg/src/fxfx_agg_vcgen_dash.cpp deleted file mode 100644 index 4a259c022c..0000000000 --- a/core/src/fxge/agg/src/fxfx_agg_vcgen_dash.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "../agg23/fx_agg_vcgen_dash.cpp" diff --git a/core/src/fxge/agg/src/fxfx_agg_vcgen_stroke.cpp b/core/src/fxge/agg/src/fxfx_agg_vcgen_stroke.cpp deleted file mode 100644 index 2311e1abd2..0000000000 --- a/core/src/fxge/agg/src/fxfx_agg_vcgen_stroke.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "../agg23/fx_agg_vcgen_stroke.cpp" diff --git a/core/src/fxge/apple/fx_apple_platform.cpp b/core/src/fxge/apple/fx_apple_platform.cpp index 07c5b6cf98..9db807c3af 100644 --- a/core/src/fxge/apple/fx_apple_platform.cpp +++ b/core/src/fxge/apple/fx_apple_platform.cpp @@ -6,15 +6,16 @@ #include "../../../include/fxcrt/fx_system.h" #include "../../../include/fxge/fx_ge.h" + #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ -#include "apple_int.h" + +#include "../../../include/fxge/fx_freetype.h" #include "../../../include/fxge/fx_ge_apple.h" -#include "../agg/include/fxfx_agg_clip_liang_barsky.h" -#include "../ge/text_int.h" -#include "../dib/dib_int.h" #include "../agg/include/fx_agg_driver.h" -#include "../../../include/fxge/fx_freetype.h" -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#include "../dib/dib_int.h" +#include "../ge/text_int.h" +#include "apple_int.h" + void CFX_AggDeviceDriver::InitPlatform() { CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; @@ -169,5 +170,5 @@ void CFX_Font::ReleasePlatformResource() m_pPlatformFont = NULL; } } -#endif -#endif + +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ diff --git a/core/src/fxge/apple/fx_quartz_device.cpp b/core/src/fxge/apple/fx_quartz_device.cpp index 0638e15f78..8f0f4db6ba 100644 --- a/core/src/fxge/apple/fx_quartz_device.cpp +++ b/core/src/fxge/apple/fx_quartz_device.cpp @@ -5,12 +5,12 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../../include/fxcrt/fx_ext.h" +#include "../../../include/fxge/fx_freetype.h" #include "../../../include/fxge/fx_ge.h" -#include "../agg/include/fxfx_agg_clip_liang_barsky.h" -#include "../ge/text_int.h" -#include "../dib/dib_int.h" #include "../agg/include/fx_agg_driver.h" -#include "../../../include/fxge/fx_freetype.h" +#include "../dib/dib_int.h" +#include "../ge/text_int.h" + #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ #include "apple_int.h" #include "../../../include/fxge/fx_ge_apple.h" @@ -1125,4 +1125,4 @@ FX_BOOL CFX_QuartzDevice::Create(int32_t width, int32_t height, FXDIB_Format for m_bOwnedBitmap = TRUE; return Attach(pBitmap); } -#endif +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ diff --git a/core/src/fxge/ge/fx_ge_linux.cpp b/core/src/fxge/ge/fx_ge_linux.cpp index 4bd0468ac3..631ff8e93f 100644 --- a/core/src/fxge/ge/fx_ge_linux.cpp +++ b/core/src/fxge/ge/fx_ge_linux.cpp @@ -7,6 +7,7 @@ #include "../../../include/fxge/fx_ge.h" #include "../agg/include/fx_agg_driver.h" #include "text_int.h" + #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ static const struct { const FX_CHAR* m_pName; @@ -228,4 +229,4 @@ void CFX_GEModule::InitPlatform() void CFX_GEModule::DestroyPlatform() { } -#endif +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ diff --git a/core/src/fxge/win32/fx_win32_device.cpp b/core/src/fxge/win32/fx_win32_device.cpp index 881502999d..f9da1cc706 100644 --- a/core/src/fxge/win32/fx_win32_device.cpp +++ b/core/src/fxge/win32/fx_win32_device.cpp @@ -5,17 +5,19 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../../include/fxge/fx_ge.h" + #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ -#include "../../../include/fxge/fx_ge_win32.h" #include -#include "../agg/include/fxfx_agg_clip_liang_barsky.h" + +#include "../../../include/fxcodec/fx_codec.h" +#include "../../../include/fxge/fx_freetype.h" +#include "../../../include/fxge/fx_ge_win32.h" +#include "../agg/include/fx_agg_driver.h" +#include "../dib/dib_int.h" +#include "../ge/text_int.h" #include "dwrite_int.h" #include "win32_int.h" -#include "../ge/text_int.h" -#include "../dib/dib_int.h" -#include "../agg/include/fx_agg_driver.h" -#include "../../../include/fxge/fx_freetype.h" -#include "../../../include/fxcodec/fx_codec.h" + class CWin32FontInfo final : public IFX_SystemFontInfo { public: @@ -1200,4 +1202,5 @@ CFX_WinBitmapDevice::~CFX_WinBitmapDevice() } delete GetBitmap(); } -#endif + +#endif // _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ diff --git a/pdfium.gyp b/pdfium.gyp index c8894aa569..3bcd1f6696 100644 --- a/pdfium.gyp +++ b/pdfium.gyp @@ -551,7 +551,12 @@ { 'target_name': 'fxge', 'type': 'static_library', - 'ldflags': [ '-L<(PRODUCT_DIR)',], + 'ldflags': [ + '-L<(PRODUCT_DIR)', + ], + 'dependencies': [ + 'third_party/third_party.gyp:fx_agg', + ], 'sources': [ 'core/include/fxge/fpf.h', 'core/include/fxge/fx_dib.h', @@ -560,23 +565,8 @@ 'core/include/fxge/fx_ge.h', 'core/include/fxge/fx_ge_apple.h', 'core/include/fxge/fx_ge_win32.h', - 'core/src/fxge/agg/include/fxfx_agg_basics.h', - 'core/src/fxge/agg/include/fxfx_agg_clip_liang_barsky.h', - 'core/src/fxge/agg/include/fxfx_agg_conv_dash.h', - 'core/src/fxge/agg/include/fxfx_agg_conv_stroke.h', - 'core/src/fxge/agg/include/fxfx_agg_curves.h', - 'core/src/fxge/agg/include/fxfx_agg_path_storage.h', - 'core/src/fxge/agg/include/fxfx_agg_rasterizer_scanline_aa.h', - 'core/src/fxge/agg/include/fxfx_agg_renderer_scanline.h', - 'core/src/fxge/agg/include/fxfx_agg_rendering_buffer.h', - 'core/src/fxge/agg/include/fxfx_agg_scanline_u.h', 'core/src/fxge/agg/include/fx_agg_driver.h', - 'core/src/fxge/agg/src/fxfx_agg_curves.cpp', - 'core/src/fxge/agg/src/fxfx_agg_driver.cpp', - 'core/src/fxge/agg/src/fxfx_agg_path_storage.cpp', - 'core/src/fxge/agg/src/fxfx_agg_rasterizer_scanline_aa.cpp', - 'core/src/fxge/agg/src/fxfx_agg_vcgen_dash.cpp', - 'core/src/fxge/agg/src/fxfx_agg_vcgen_stroke.cpp', + 'core/src/fxge/agg/src/fx_agg_driver.cpp', 'core/src/fxge/android/fpf_skiafont.cpp', 'core/src/fxge/android/fpf_skiafont.h', 'core/src/fxge/android/fpf_skiafontmgr.cpp', diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn index 18baeb2eb5..bcb7cbabee 100644 --- a/third_party/BUILD.gn +++ b/third_party/BUILD.gn @@ -30,6 +30,31 @@ source_set("bigint") { ] } +source_set("fx_agg") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + "//build/config/compiler:no_chromium_code", + "//third_party/pdfium:pdfium_config", + ] + sources = [ + "agg23/agg_basics.h", + "agg23/agg_clip_liang_barsky.h", + "agg23/agg_conv_dash.h", + "agg23/agg_conv_stroke.h", + "agg23/agg_curves.cpp", + "agg23/agg_curves.h", + "agg23/agg_path_storage.cpp", + "agg23/agg_path_storage.h", + "agg23/agg_rasterizer_scanline_aa.cpp", + "agg23/agg_rasterizer_scanline_aa.h", + "agg23/agg_renderer_scanline.h", + "agg23/agg_rendering_buffer.h", + "agg23/agg_scanline_u.h", + "agg23/agg_vcgen_dash.cpp", + "agg23/agg_vcgen_stroke.cpp", + ] +} + source_set("freetype") { configs -= [ "//build/config/compiler:chromium_code" ] configs += [ diff --git a/third_party/agg23/agg_array.h b/third_party/agg23/agg_array.h new file mode 100644 index 0000000000..810eb4ef22 --- /dev/null +++ b/third_party/agg23/agg_array.h @@ -0,0 +1,506 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_ARRAY_INCLUDED +#define AGG_ARRAY_INCLUDED +#include "agg_basics.h" +namespace agg +{ +template class pod_array +{ +public: + typedef T value_type; + ~pod_array() + { + FX_Free(m_array); + } + pod_array() : m_size(0), m_capacity(0), m_array(0) {} + pod_array(unsigned cap, unsigned extra_tail = 0); + pod_array(const pod_array&); + const pod_array& operator = (const pod_array&); + void capacity(unsigned cap, unsigned extra_tail = 0); + unsigned capacity() const + { + return m_capacity; + } + void allocate(unsigned size, unsigned extra_tail = 0); + void resize(unsigned new_size); + void zero() + { + FXSYS_memset(m_array, 0, sizeof(T) * m_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); + } + 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 cut_at(unsigned num) + { + if(num < m_size) { + m_size = num; + } + } +private: + unsigned m_size; + unsigned m_capacity; + T* m_array; +}; +template +void pod_array::capacity(unsigned cap, unsigned extra_tail) +{ + m_size = 0; + unsigned full_cap = cap + extra_tail; + if(full_cap < cap) { + FX_Free(m_array); + m_array = 0; + m_capacity = 0; + } else if(full_cap > m_capacity) { + FX_Free(m_array); + m_array = FX_Alloc(T, full_cap); + m_capacity = full_cap; + } +} +template +void pod_array::allocate(unsigned size, unsigned extra_tail) +{ + capacity(size, extra_tail); + m_size = size; +} +template +void pod_array::resize(unsigned new_size) +{ + if(new_size > m_size) { + if(new_size > m_capacity) { + T* data = FX_Alloc(T, new_size); + FXSYS_memcpy(data, m_array, m_size * sizeof(T)); + FX_Free(m_array); + m_array = data; + } + } else { + m_size = new_size; + } +} +template pod_array::pod_array(unsigned cap, unsigned extra_tail) : + m_size(0), m_capacity(cap + extra_tail), m_array(FX_Alloc(T, m_capacity)) {} +template pod_array::pod_array(const pod_array& v) : + m_size(v.m_size), + m_capacity(v.m_capacity), + m_array(v.m_capacity ? FX_Alloc(T, v.m_capacity) : 0) +{ + FXSYS_memcpy(m_array, v.m_array, sizeof(T) * v.m_size); +} +template const pod_array& +pod_array::operator = (const pod_array&v) +{ + allocate(v.m_size); + if(v.m_size) { + FXSYS_memcpy(m_array, v.m_array, sizeof(T) * v.m_size); + } + return *this; +} +template class pod_deque +{ +public: + enum block_scale_e { + block_shift = S, + block_size = 1 << block_shift, + block_mask = block_size - 1 + }; + typedef T value_type; + ~pod_deque(); + pod_deque(); + pod_deque(unsigned block_ptr_inc); + pod_deque(const pod_deque& v); + const pod_deque& operator = (const pod_deque& v); + void remove_all() + { + m_size = 0; + } + void free_all() + { + free_tail(0); + } + void free_tail(unsigned size); + void add(const T& val); + void modify_last(const T& val); + void remove_last(); + int allocate_continuous_block(unsigned num_elements); + void add_array(const T* ptr, unsigned num_elem) + { + while(num_elem--) { + add(*ptr++); + } + } + template void add_data(DataAccessor& data) + { + while(data.size()) { + add(*data); + ++data; + } + } + void cut_at(unsigned size) + { + if(size < m_size) { + m_size = size; + } + } + unsigned size() const + { + return m_size; + } + const T& operator [] (unsigned i) const + { + return m_blocks[i >> block_shift][i & block_mask]; + } + T& operator [] (unsigned i) + { + 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 + { + return (*this)[idx]; + } + T& curr(unsigned idx) + { + return (*this)[idx]; + } + const T& prev(unsigned idx) const + { + return (*this)[(idx + m_size - 1) % m_size]; + } + T& prev(unsigned idx) + { + return (*this)[(idx + m_size - 1) % m_size]; + } + const T& next(unsigned idx) const + { + return (*this)[(idx + 1) % m_size]; + } + T& next(unsigned idx) + { + return (*this)[(idx + 1) % m_size]; + } + const T& last() const + { + return (*this)[m_size - 1]; + } + T& last() + { + return (*this)[m_size - 1]; + } + unsigned byte_size() const; + const T* block(unsigned nb) const + { + return m_blocks[nb]; + } +public: + void allocate_block(unsigned nb); + T* data_ptr(); + unsigned m_size; + unsigned m_num_blocks; + unsigned m_max_blocks; + T** m_blocks; + unsigned m_block_ptr_inc; +}; +template pod_deque::~pod_deque() +{ + if(m_num_blocks) { + T** blk = m_blocks + m_num_blocks - 1; + while(m_num_blocks--) { + FX_Free(*blk); + --blk; + } + FX_Free(m_blocks); + } +} +template +void pod_deque::free_tail(unsigned size) +{ + if(size < m_size) { + unsigned nb = (size + block_mask) >> block_shift; + while(m_num_blocks > nb) { + FX_Free(m_blocks[--m_num_blocks]); + } + m_size = size; + } +} +template pod_deque::pod_deque() : + m_size(0), + m_num_blocks(0), + m_max_blocks(0), + m_blocks(0), + m_block_ptr_inc(block_size) +{ +} +template +pod_deque::pod_deque(unsigned block_ptr_inc) : + m_size(0), + m_num_blocks(0), + m_max_blocks(0), + m_blocks(0), + m_block_ptr_inc(block_ptr_inc) +{ +} +template +pod_deque::pod_deque(const pod_deque& 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 ? FX_Alloc(T*, 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] = FX_Alloc(T, block_size); + FXSYS_memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); + } +} +template +const pod_deque& pod_deque::operator = (const pod_deque& v) +{ + unsigned i; + for(i = m_num_blocks; i < v.m_num_blocks; ++i) { + allocate_block(i); + } + for(i = 0; i < v.m_num_blocks; ++i) { + FXSYS_memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); + } + m_size = v.m_size; + return *this; +} +template +void pod_deque::allocate_block(unsigned nb) +{ + if(nb >= m_max_blocks) { + T** new_blocks = FX_Alloc(T*, m_max_blocks + m_block_ptr_inc); + if(m_blocks) { + FXSYS_memcpy(new_blocks, + m_blocks, + m_num_blocks * sizeof(T*)); + FX_Free(m_blocks); + } + m_blocks = new_blocks; + m_max_blocks += m_block_ptr_inc; + } + m_blocks[nb] = FX_Alloc(T, block_size); + m_num_blocks++; +} +template +inline T* pod_deque::data_ptr() +{ + unsigned nb = m_size >> block_shift; + if(nb >= m_num_blocks) { + allocate_block(nb); + } + return m_blocks[nb] + (m_size & block_mask); +} +template +inline void pod_deque::add(const T& val) +{ + *data_ptr() = val; + ++m_size; +} +template +inline void pod_deque::remove_last() +{ + if(m_size) { + --m_size; + } +} +template +void pod_deque::modify_last(const T& val) +{ + remove_last(); + add(val); +} +template +int pod_deque::allocate_continuous_block(unsigned num_elements) +{ + if(num_elements < block_size) { + data_ptr(); + unsigned rest = block_size - (m_size & block_mask); + unsigned index; + if(num_elements <= rest) { + index = m_size; + m_size += num_elements; + return index; + } + m_size += rest; + data_ptr(); + index = m_size; + m_size += num_elements; + return index; + } + return -1; +} +template +unsigned pod_deque::byte_size() const +{ + return m_size * sizeof(T); +} +class pod_allocator +{ +public: + void remove_all() + { + if(m_num_blocks) { + int8u** blk = m_blocks + m_num_blocks - 1; + while(m_num_blocks--) { + FX_Free(*blk); + --blk; + } + FX_Free(m_blocks); + } + m_num_blocks = 0; + m_max_blocks = 0; + m_blocks = 0; + m_buf_ptr = 0; + m_rest = 0; + } + ~pod_allocator() + { + remove_all(); + } + pod_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), + m_max_blocks(0), + m_blocks(0), + m_buf_ptr(0), + m_rest(0) + { + } + int8u* allocate(unsigned size, unsigned alignment = 1) + { + if(size == 0) { + return 0; + } + if(size <= m_rest) { + int8u* ptr = m_buf_ptr; + if(alignment > 1) { + unsigned align = (alignment - unsigned((size_t)ptr) % alignment) % alignment; + size += align; + ptr += align; + if(size <= m_rest) { + m_rest -= size; + m_buf_ptr += size; + return ptr; + } + allocate_block(size); + return allocate(size - align, alignment); + } + m_rest -= size; + m_buf_ptr += size; + return ptr; + } + allocate_block(size + alignment - 1); + return allocate(size, alignment); + } +private: + void allocate_block(unsigned size) + { + if(size < m_block_size) { + size = m_block_size; + } + if(m_num_blocks >= m_max_blocks) { + int8u** new_blocks = FX_Alloc(int8u*, m_max_blocks + m_block_ptr_inc); + if(m_blocks) { + FXSYS_memcpy(new_blocks, + m_blocks, + m_num_blocks * sizeof(int8u*)); + FX_Free(m_blocks); + } + m_blocks = new_blocks; + m_max_blocks += m_block_ptr_inc; + } + m_blocks[m_num_blocks] = m_buf_ptr = FX_Alloc(int8u, 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; +}; +enum quick_sort_threshold_e { + quick_sort_threshold = 9 +}; +template inline void swap_elements(T& a, T& b) +{ + T temp = a; + a = b; + b = temp; +} +} +#endif diff --git a/third_party/agg23/agg_basics.h b/third_party/agg23/agg_basics.h new file mode 100644 index 0000000000..d2fad58feb --- /dev/null +++ b/third_party/agg23/agg_basics.h @@ -0,0 +1,282 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_BASICS_INCLUDED +#define AGG_BASICS_INCLUDED +#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 +#define AGG_INT64 signed long long +#endif +#ifndef AGG_INT64U +#define AGG_INT64U unsigned long long +#endif +#define AGG_INLINE inline +namespace agg +{ +typedef AGG_INT8 int8; +typedef AGG_INT8U int8u; +typedef AGG_INT16 int16; +typedef AGG_INT16U int16u; +typedef AGG_INT32 int32; +typedef AGG_INT32U int32u; +typedef AGG_INT64 int64; +typedef AGG_INT64U int64u; +typedef unsigned char cover_type; +enum cover_scale_e { + cover_shift = 8, + cover_size = 1 << cover_shift, + cover_mask = cover_size - 1, + cover_none = 0, + cover_full = cover_mask +}; +template struct rect_base { + typedef rect_base self_type; + T x1; + T y1; + T x2; + T y2; + rect_base() {} + rect_base(T x1_, T y1_, T x2_, T y2_) : + x1(x1_), y1(y1_), x2(x2_), y2(y2_) {} + const self_type& normalize() + { + T t; + if(x1 > x2) { + t = x1; + x1 = x2; + x2 = t; + } + if(y1 > y2) { + t = y1; + y1 = y2; + y2 = t; + } + return *this; + } + bool clip(const self_type& r) + { + if(x2 > r.x2) { + x2 = r.x2; + } + if(y2 > r.y2) { + y2 = r.y2; + } + if(x1 < r.x1) { + x1 = r.x1; + } + if(y1 < r.y1) { + y1 = r.y1; + } + return x1 <= x2 && y1 <= y2; + } + bool is_valid() const + { + return x1 <= x2 && y1 <= y2; + } +}; +template +inline Rect intersect_rectangles(const Rect& r1, const Rect& r2) +{ + Rect r = r1; + if(r.x2 > r2.x2) { + r.x2 = r2.x2; + } + if(r.y2 > r2.y2) { + r.y2 = r2.y2; + } + if(r.x1 < r2.x1) { + r.x1 = r2.x1; + } + if(r.y1 < r2.y1) { + r.y1 = r2.y1; + } + return r; +} +template +inline Rect unite_rectangles(const Rect& r1, const Rect& r2) +{ + Rect r = r1; + if(r.x2 < r2.x2) { + r.x2 = r2.x2; + } + if(r.y2 < r2.y2) { + r.y2 = r2.y2; + } + if(r.x1 > r2.x1) { + r.x1 = r2.x1; + } + if(r.y1 > r2.y1) { + r.y1 = r2.y1; + } + return r; +} +typedef rect_base rect; +typedef rect_base rect_d; +enum path_commands_e { + path_cmd_stop = 0, + path_cmd_move_to = 1, + path_cmd_line_to = 2, + path_cmd_curve3 = 3, + path_cmd_curve4 = 4, + path_cmd_curveN = 5, + path_cmd_catrom = 6, + path_cmd_ubspline = 7, + path_cmd_end_poly = 0x0F, + path_cmd_mask = 0x0F +}; +enum path_flags_e { + path_flags_none = 0, + path_flags_ccw = 0x10, + path_flags_cw = 0x20, + path_flags_close = 0x40, + path_flags_jr = 0x80, + path_flags_mask = 0xF0 +}; +inline bool is_vertex(unsigned c) +{ + c &= ~path_flags_jr; + return c >= path_cmd_move_to && c < path_cmd_end_poly; +} +inline bool is_drawing(unsigned c) +{ + c &= ~path_flags_jr; + return c >= path_cmd_line_to && c < path_cmd_end_poly; +} +inline bool is_stop(unsigned c) +{ + c &= ~path_flags_jr; + return c == path_cmd_stop; +} +inline bool is_move_to(unsigned c) +{ + c &= ~path_flags_jr; + return c == path_cmd_move_to; +} +inline bool is_line_to(unsigned c) +{ + c &= ~path_flags_jr; + return c == path_cmd_line_to; +} +inline bool is_curve(unsigned c) +{ + c &= ~path_flags_jr; + return c == path_cmd_curve3 || c == path_cmd_curve4; +} +inline bool is_curve3(unsigned c) +{ + c &= ~path_flags_jr; + return c == path_cmd_curve3; +} +inline bool is_curve4(unsigned c) +{ + c &= ~path_flags_jr; + return c == path_cmd_curve4; +} +inline bool is_end_poly(unsigned c) +{ + c &= ~path_flags_jr; + return (c & path_cmd_mask) == path_cmd_end_poly; +} +inline bool is_close(unsigned c) +{ + c &= ~path_flags_jr; + return (c & ~(path_flags_cw | path_flags_ccw)) == + (path_cmd_end_poly | path_flags_close); +} +inline bool is_next_poly(unsigned c) +{ + c &= ~path_flags_jr; + return is_stop(c) || is_move_to(c) || is_end_poly(c); +} +inline bool is_cw(unsigned c) +{ + c &= ~path_flags_jr; + return (c & path_flags_cw) != 0; +} +inline bool is_ccw(unsigned c) +{ + c &= ~path_flags_jr; + return (c & path_flags_ccw) != 0; +} +inline bool is_oriented(unsigned c) +{ + c &= ~path_flags_jr; + return (c & (path_flags_cw | path_flags_ccw)) != 0; +} +inline bool is_closed(unsigned c) +{ + c &= ~path_flags_jr; + return (c & path_flags_close) != 0; +} +inline unsigned get_close_flag(unsigned c) +{ + c &= ~path_flags_jr; + return c & path_flags_close; +} +inline unsigned clear_orientation(unsigned c) +{ + c &= ~path_flags_jr; + return c & ~(path_flags_cw | path_flags_ccw); +} +inline unsigned get_orientation(unsigned c) +{ + c &= ~path_flags_jr; + return c & (path_flags_cw | path_flags_ccw); +} +inline unsigned set_orientation(unsigned c, unsigned o) +{ + c &= ~path_flags_jr; + return clear_orientation(c) | o; +} +struct point_type { + FX_FLOAT x, y; + unsigned flag; + point_type() {} + point_type(FX_FLOAT x_, FX_FLOAT y_, unsigned flag_ = 0) : x(x_), y(y_), flag(flag_) {} +}; +struct point_type_flag : public point_type { + unsigned flag; + point_type_flag() + { + flag = 0; + } + point_type_flag(FX_FLOAT x_, FX_FLOAT y_, unsigned flag_ = 0) : point_type(x_, y_), flag(flag_) {} +}; +struct vertex_type { + FX_FLOAT x, y; + unsigned cmd; + vertex_type() {} + vertex_type(FX_FLOAT x_, FX_FLOAT y_, unsigned cmd_) : + x(x_), y(y_), cmd(cmd_) {} +}; +} +#endif diff --git a/third_party/agg23/agg_clip_liang_barsky.h b/third_party/agg23/agg_clip_liang_barsky.h new file mode 100644 index 0000000000..cfc4c91f60 --- /dev/null +++ b/third_party/agg23/agg_clip_liang_barsky.h @@ -0,0 +1,125 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Liang-Barsky clipping +// +//---------------------------------------------------------------------------- +#ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED +#define AGG_CLIP_LIANG_BARSKY_INCLUDED +#include "agg_basics.h" +namespace agg +{ +template +inline unsigned clipping_flags(T x, T y, const rect_base& clip_box) +{ + return (x > clip_box.x2) | + ((y > clip_box.y2) << 1) | + ((x < clip_box.x1) << 2) | + ((y < clip_box.y1) << 3); +} +template +inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2, + const rect_base& clip_box, + T* x, T* y) +{ + const FX_FLOAT nearzero = 1e-30f; + FX_FLOAT deltax = (FX_FLOAT)(x2 - x1); + FX_FLOAT deltay = (FX_FLOAT)(y2 - y1); + unsigned np = 0; + if(deltax == 0) { + deltax = (x1 > clip_box.x1) ? -nearzero : nearzero; + } + FX_FLOAT xin, xout; + if(deltax > 0) { + xin = (FX_FLOAT)clip_box.x1; + xout = (FX_FLOAT)clip_box.x2; + } else { + xin = (FX_FLOAT)clip_box.x2; + xout = (FX_FLOAT)clip_box.x1; + } + FX_FLOAT tinx = FXSYS_Div(xin - x1, deltax); + if(deltay == 0) { + deltay = (y1 > clip_box.y1) ? -nearzero : nearzero; + } + FX_FLOAT yin, yout; + if(deltay > 0) { + yin = (FX_FLOAT)clip_box.y1; + yout = (FX_FLOAT)clip_box.y2; + } else { + yin = (FX_FLOAT)clip_box.y2; + yout = (FX_FLOAT)clip_box.y1; + } + FX_FLOAT tiny = FXSYS_Div(yin - y1, deltay); + FX_FLOAT tin1, tin2; + if (tinx < tiny) { + tin1 = tinx; + tin2 = tiny; + } else { + tin1 = tiny; + tin2 = tinx; + } + if(tin1 <= 1.0f) { + if(0 < tin1) { + *x++ = (T)xin; + *y++ = (T)yin; + ++np; + } + if(tin2 <= 1.0f) { + FX_FLOAT toutx = FXSYS_Div(xout - x1, deltax); + FX_FLOAT touty = FXSYS_Div(yout - y1, deltay); + FX_FLOAT tout1 = (toutx < touty) ? toutx : touty; + if(tin2 > 0 || tout1 > 0) { + if(tin2 <= tout1) { + if(tin2 > 0) { + if(tinx > tiny) { + *x++ = (T)xin; + *y++ = (T)(y1 + FXSYS_Mul(deltay, tinx)); + } else { + *x++ = (T)(x1 + FXSYS_Mul(deltax, tiny)); + *y++ = (T)yin; + } + ++np; + } + if(tout1 < 1.0f) { + if(toutx < touty) { + *x++ = (T)xout; + *y++ = (T)(y1 + FXSYS_Mul(deltay, toutx)); + } else { + *x++ = (T)(x1 + FXSYS_Mul(deltax, touty)); + *y++ = (T)yout; + } + } else { + *x++ = x2; + *y++ = y2; + } + ++np; + } else { + if(tinx > tiny) { + *x++ = (T)xin; + *y++ = (T)yout; + } else { + *x++ = (T)xout; + *y++ = (T)yin; + } + ++np; + } + } + } + } + return np; +} +} +#endif diff --git a/third_party/agg23/agg_color_gray.h b/third_party/agg23/agg_color_gray.h new file mode 100644 index 0000000000..5db7bcaf28 --- /dev/null +++ b/third_party/agg23/agg_color_gray.h @@ -0,0 +1,50 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// 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" +namespace agg +{ +struct gray8 { + typedef int8u value_type; + typedef int32u calc_type; + typedef int32 long_type; + enum base_scale_e { + base_shift = 8, + base_size = 1 << base_shift, + base_mask = base_size - 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_)) {} +}; +} +#endif diff --git a/third_party/agg23/agg_conv_adaptor_vcgen.h b/third_party/agg23/agg_conv_adaptor_vcgen.h new file mode 100644 index 0000000000..0d8d6ff99e --- /dev/null +++ b/third_party/agg23/agg_conv_adaptor_vcgen.h @@ -0,0 +1,138 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED +#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED +#include "agg_basics.h" +namespace agg +{ +struct null_markers { + void remove_all() {} + void add_vertex(FX_FLOAT, FX_FLOAT, unsigned) {} + void prepare_src() {} + void rewind(unsigned) {} + unsigned vertex(FX_FLOAT*, FX_FLOAT*) + { + return path_cmd_stop; + } +}; +template class conv_adaptor_vcgen +{ + enum status { + initial, + accumulate, + generate + }; +public: + conv_adaptor_vcgen(VertexSource& source) : + m_source(&source), + m_status(initial) + {} + void set_source(VertexSource& source) + { + m_source = &source; + } + Generator& generator() + { + return m_generator; + } + const Generator& generator() const + { + return m_generator; + } + Markers& markers() + { + return m_markers; + } + const Markers& markers() const + { + return m_markers; + } + void rewind(unsigned path_id) + { + m_source->rewind(path_id); + m_status = initial; + } + unsigned vertex(FX_FLOAT* x, FX_FLOAT* y); +private: + conv_adaptor_vcgen(const conv_adaptor_vcgen&); + const conv_adaptor_vcgen& + operator = (const conv_adaptor_vcgen&); + VertexSource* m_source; + Generator m_generator; + Markers m_markers; + status m_status; + unsigned m_last_cmd; + FX_FLOAT m_start_x; + FX_FLOAT m_start_y; +}; +template +unsigned conv_adaptor_vcgen::vertex(FX_FLOAT* x, FX_FLOAT* y) +{ + unsigned cmd = path_cmd_stop; + bool done = false; + while(!done) { + switch(m_status) { + case initial: + m_markers.remove_all(); + m_last_cmd = m_source->vertex(&m_start_x, &m_start_y); + m_status = accumulate; + case accumulate: + if(is_stop(m_last_cmd)) { + return path_cmd_stop; + } + m_generator.remove_all(); + m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to); + m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to); + for(;;) { + cmd = m_source->vertex(x, y); + if(is_vertex(cmd)) { + m_last_cmd = cmd; + if(is_move_to(cmd)) { + m_start_x = *x; + m_start_y = *y; + break; + } + m_generator.add_vertex(*x, *y, cmd); + m_markers.add_vertex(*x, *y, path_cmd_line_to); + } else { + if(is_stop(cmd)) { + m_last_cmd = path_cmd_stop; + break; + } + if(is_end_poly(cmd)) { + m_generator.add_vertex(*x, *y, cmd); + break; + } + } + } + m_generator.rewind(0); + m_status = generate; + case generate: + cmd = m_generator.vertex(x, y); + if(is_stop(cmd)) { + m_status = accumulate; + break; + } + done = true; + break; + } + } + return cmd; +} +} +#endif diff --git a/third_party/agg23/agg_conv_dash.h b/third_party/agg23/agg_conv_dash.h new file mode 100644 index 0000000000..63b2019dde --- /dev/null +++ b/third_party/agg23/agg_conv_dash.h @@ -0,0 +1,61 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// conv_dash +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_DASH_INCLUDED +#define AGG_CONV_DASH_INCLUDED +#include "agg_basics.h" +#include "agg_vcgen_dash.h" +#include "agg_conv_adaptor_vcgen.h" +namespace agg +{ +template +struct conv_dash : public conv_adaptor_vcgen { + typedef Markers marker_type; + typedef conv_adaptor_vcgen base_type; + conv_dash(VertexSource& vs) : + conv_adaptor_vcgen(vs) + { + } + void remove_all_dashes() + { + base_type::generator().remove_all_dashes(); + } + void add_dash(FX_FLOAT dash_len, FX_FLOAT gap_len) + { + base_type::generator().add_dash(dash_len, gap_len); + } + void dash_start(FX_FLOAT ds) + { + base_type::generator().dash_start(ds); + } + void shorten(FX_FLOAT s) + { + base_type::generator().shorten(s); + } + double shorten() const + { + return base_type::generator().shorten(); + } +private: + conv_dash(const conv_dash&); + const conv_dash& + operator = (const conv_dash&); +}; +} +#endif diff --git a/third_party/agg23/agg_conv_stroke.h b/third_party/agg23/agg_conv_stroke.h new file mode 100644 index 0000000000..5a36bd73bb --- /dev/null +++ b/third_party/agg23/agg_conv_stroke.h @@ -0,0 +1,110 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// conv_stroke +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_STROKE_INCLUDED +#define AGG_CONV_STROKE_INCLUDED +#include "agg_basics.h" +#include "agg_vcgen_stroke.h" +#include "agg_conv_adaptor_vcgen.h" +namespace agg +{ +template +struct conv_stroke : + public conv_adaptor_vcgen { + typedef Markers marker_type; + typedef conv_adaptor_vcgen base_type; + conv_stroke(VertexSource& vs) : + conv_adaptor_vcgen(vs) + { + } + 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(); + } + inner_join_e inner_join() const + { + return base_type::generator().inner_join(); + } + void width(FX_FLOAT w) + { + base_type::generator().width(w); + } + void miter_limit(FX_FLOAT ml) + { + base_type::generator().miter_limit(ml); + } + void miter_limit_theta(FX_FLOAT t) + { + base_type::generator().miter_limit_theta(t); + } + void inner_miter_limit(FX_FLOAT ml) + { + base_type::generator().inner_miter_limit(ml); + } + void approximation_scale(FX_FLOAT as) + { + base_type::generator().approximation_scale(as); + } + FX_FLOAT width() const + { + return base_type::generator().width(); + } + FX_FLOAT miter_limit() const + { + return base_type::generator().miter_limit(); + } + FX_FLOAT inner_miter_limit() const + { + return base_type::generator().inner_miter_limit(); + } + FX_FLOAT approximation_scale() const + { + return base_type::generator().approximation_scale(); + } + void shorten(FX_FLOAT s) + { + base_type::generator().shorten(s); + } + FX_FLOAT shorten() const + { + return base_type::generator().shorten(); + } +private: + conv_stroke(const conv_stroke&); + const conv_stroke& + operator = (const conv_stroke&); +}; +} +#endif diff --git a/third_party/agg23/agg_curves.cpp b/third_party/agg23/agg_curves.cpp new file mode 100644 index 0000000000..5a2d5631d6 --- /dev/null +++ b/third_party/agg23/agg_curves.cpp @@ -0,0 +1,109 @@ + +//---------------------------------------------------------------------------- +// XYQ: 2006-01-22 Copied from AGG project. +// TODO: This file uses intensive floating point operations, so it's NOT suitable +// for platforms like Symbian OS. We need to change to FIX format. +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#include "../../core/include/fxcrt/fx_basic.h" +#include "agg_curves.h" +#include "agg_math.h" +namespace agg +{ +const FX_FLOAT curve_collinearity_epsilon = 1e-30f; +enum curve_recursion_limit_e { curve_recursion_limit = 16 }; +void curve4_div::init(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT y4) +{ + m_points.remove_all(); + m_distance_tolerance_square = 1.0f / 4; + m_distance_tolerance_manhattan = 1.0f * 4; + bezier(x1, y1, x2, y2, x3, y3, x4, y4); + m_count = 0; +} +void curve4_div::recursive_bezier(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT y4, + unsigned level) +{ + if(level > curve_recursion_limit) { + return; + } + FX_FLOAT x12 = (x1 + x2) / 2; + FX_FLOAT y12 = (y1 + y2) / 2; + FX_FLOAT x23 = (x2 + x3) / 2; + FX_FLOAT y23 = (y2 + y3) / 2; + FX_FLOAT x34 = (x3 + x4) / 2; + FX_FLOAT y34 = (y3 + y4) / 2; + FX_FLOAT x123 = (x12 + x23) / 2; + FX_FLOAT y123 = (y12 + y23) / 2; + FX_FLOAT x234 = (x23 + x34) / 2; + FX_FLOAT y234 = (y23 + y34) / 2; + FX_FLOAT x1234 = (x123 + x234) / 2; + FX_FLOAT y1234 = (y123 + y234) / 2; + FX_FLOAT dx = x4 - x1; + FX_FLOAT dy = y4 - y1; + FX_FLOAT d2 = FXSYS_fabs(FXSYS_Mul(x2 - x4, dy) - FXSYS_Mul(y2 - y4, dx)); + FX_FLOAT d3 = FXSYS_fabs(FXSYS_Mul(x3 - x4, dy) - FXSYS_Mul(y3 - y4, dx)); + switch((int(d2 > curve_collinearity_epsilon) << 1) + + int(d3 > curve_collinearity_epsilon)) { + case 0: + if(FXSYS_fabs(x1 + x3 - x2 - x2) + + FXSYS_fabs(y1 + y3 - y2 - y2) + + FXSYS_fabs(x2 + x4 - x3 - x3) + + FXSYS_fabs(y2 + y4 - y3 - y3) <= m_distance_tolerance_manhattan) { + m_points.add(point_type(x1234, y1234, path_flags_jr)); + return; + } + break; + case 1: + if(FXSYS_Mul(d3, d3) <= FXSYS_Mul(m_distance_tolerance_square, + FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy))) { + m_points.add(point_type(x23, y23, path_flags_jr)); + return; + } + break; + case 2: + if(FXSYS_Mul(d2, d2) <= FXSYS_Mul(m_distance_tolerance_square, + FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy))) { + m_points.add(point_type(x23, y23, path_flags_jr)); + return; + } + break; + case 3: + if(FXSYS_Mul(d2 + d3, d2 + d3) <= FXSYS_Mul(m_distance_tolerance_square, + FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy))) { + m_points.add(point_type(x23, y23, path_flags_jr)); + return; + } + break; + } + 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(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT y4) +{ + m_points.add(point_type(x1, y1)); + recursive_bezier(x1, y1, x2, y2, x3, y3, x4, y4, 0); + m_points.add(point_type(x4, y4)); +} +} diff --git a/third_party/agg23/agg_curves.h b/third_party/agg23/agg_curves.h new file mode 100644 index 0000000000..495f7a6a8f --- /dev/null +++ b/third_party/agg23/agg_curves.h @@ -0,0 +1,188 @@ + +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// 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. +// 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_CURVES_INCLUDED +#define AGG_CURVES_INCLUDED +#include "agg_array.h" +namespace agg +{ +struct curve4_points { + FX_FLOAT cp[8]; + curve4_points() {} + curve4_points(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT 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(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT 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; + } + FX_FLOAT operator [] (unsigned i) const + { + return cp[i]; + } + FX_FLOAT& operator [] (unsigned i) + { + return cp[i]; + } +}; +class curve4_div +{ +public: + curve4_div() : + m_count(0) + {} + curve4_div(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT y4) : + m_count(0) + { + init(x1, y1, x2, y2, x3, y3, x4, y4); + } + curve4_div(const curve4_points& cp) : + 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(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT 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 rewind(unsigned) + { + m_count = 0; + } + unsigned vertex(FX_FLOAT* x, FX_FLOAT* y) + { + if(m_count >= m_points.size()) { + return path_cmd_stop; + } + const point_type& p = m_points[m_count++]; + *x = p.x; + *y = p.y; + return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; + } + unsigned vertex_flag(FX_FLOAT* x, FX_FLOAT* y, int& flag) + { + if(m_count >= m_points.size()) { + return path_cmd_stop; + } + const point_type& p = m_points[m_count++]; + *x = p.x; + *y = p.y; + flag = p.flag; + return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; + } + int count() + { + return m_points.size(); + } +private: + void bezier(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT y4); + void recursive_bezier(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT y4, + unsigned level); + FX_FLOAT m_distance_tolerance_square; + FX_FLOAT m_distance_tolerance_manhattan; + unsigned m_count; + pod_deque m_points; +}; +class curve4 +{ +public: + curve4() {} + curve4(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT y4) + { + init(x1, y1, x2, y2, x3, y3, x4, y4); + } + curve4(const curve4_points& cp) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + void reset() + { + m_curve_div.reset(); + } + void init(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x3, FX_FLOAT y3, + FX_FLOAT x4, FX_FLOAT y4) + { + 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 rewind(unsigned path_id) + { + m_curve_div.rewind(path_id); + } + unsigned vertex(FX_FLOAT* x, FX_FLOAT* y) + { + return m_curve_div.vertex(x, y); + } + unsigned vertex_curve_flag(FX_FLOAT* x, FX_FLOAT* y, int& flag) + { + return m_curve_div.vertex_flag(x, y, flag); + } + int count() + { + return m_curve_div.count(); + } +private: + curve4_div m_curve_div; +}; +} +#endif diff --git a/third_party/agg23/agg_math.h b/third_party/agg23/agg_math.h new file mode 100644 index 0000000000..31e0daf3bb --- /dev/null +++ b/third_party/agg23/agg_math.h @@ -0,0 +1,63 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// 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 +#include "agg_basics.h" +namespace agg +{ +const FX_FLOAT intersection_epsilon = 1.0e-30f; +AGG_INLINE FX_FLOAT calc_point_location(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x, FX_FLOAT y) +{ + return FXSYS_Mul(x - x2, y2 - y1) - FXSYS_Mul(y - y2, x2 - x1); +} +AGG_INLINE FX_FLOAT calc_distance(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) +{ + FX_FLOAT dx = x2 - x1; + FX_FLOAT dy = y2 - y1; + return FXSYS_sqrt2(dx, dy); +} +AGG_INLINE FX_FLOAT calc_line_point_distance(FX_FLOAT x1, FX_FLOAT y1, + FX_FLOAT x2, FX_FLOAT y2, + FX_FLOAT x, FX_FLOAT y) +{ + FX_FLOAT dx = x2 - x1; + FX_FLOAT dy = y2 - y1; + FX_FLOAT d = FXSYS_sqrt2(dx, dy); + if(d < intersection_epsilon) { + return calc_distance(x1, y1, x, y); + } + return FXSYS_MulDiv(x - x2, dy, d) - FXSYS_MulDiv(y - y2, dx, d); +} +AGG_INLINE bool calc_intersection(FX_FLOAT ax, FX_FLOAT ay, FX_FLOAT bx, FX_FLOAT by, + FX_FLOAT cx, FX_FLOAT cy, FX_FLOAT dx, FX_FLOAT dy, + FX_FLOAT* x, FX_FLOAT* y) +{ + FX_FLOAT num = FXSYS_Mul(ay - cy, dx - cx) - FXSYS_Mul(ax - cx, dy - cy); + FX_FLOAT den = FXSYS_Mul(bx - ax, dy - cy) - FXSYS_Mul(by - ay, dx - cx); + if (FXSYS_fabs(den) < intersection_epsilon) { + return false; + } + *x = ax + FXSYS_MulDiv(bx - ax, num, den); + *y = ay + FXSYS_MulDiv(by - ay, num, den); + return true; +} +} +#endif diff --git a/third_party/agg23/agg_math_stroke.h b/third_party/agg23/agg_math_stroke.h new file mode 100644 index 0000000000..620d675312 --- /dev/null +++ b/third_party/agg23/agg_math_stroke.h @@ -0,0 +1,272 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Stroke math +// +//---------------------------------------------------------------------------- +#ifndef AGG_STROKE_MATH_INCLUDED +#define AGG_STROKE_MATH_INCLUDED +#include "agg_math.h" +#include "agg_vertex_sequence.h" +namespace agg +{ +enum line_cap_e { + butt_cap, + square_cap, + round_cap +}; +enum line_join_e { + miter_join = 0, + miter_join_revert = 1, + miter_join_round = 4, + round_join = 2, + bevel_join = 3 +}; +enum inner_join_e { + inner_bevel, + inner_miter, + inner_jag, + inner_round +}; +const FX_FLOAT stroke_theta = 1.0f / 1000.0f; +template +void stroke_calc_arc(VertexConsumer& out_vertices, + FX_FLOAT x, FX_FLOAT y, + FX_FLOAT dx1, FX_FLOAT dy1, + FX_FLOAT dx2, FX_FLOAT dy2, + FX_FLOAT width, + FX_FLOAT approximation_scale) +{ + typedef typename VertexConsumer::value_type coord_type; + FX_FLOAT a1 = FXSYS_atan2(dy1, dx1); + FX_FLOAT a2 = FXSYS_atan2(dy2, dx2); + FX_FLOAT da = a1 - a2; + bool ccw = da > 0 && da < FX_PI; + if(width < 0) { + width = -width; + } + da = FXSYS_acos(FXSYS_Div(width, width + FXSYS_Div(1.0f / 8, approximation_scale))) * 2; + out_vertices.add(coord_type(x + dx1, y + dy1)); + if(!ccw) { + if(a1 > a2) { + a2 += 2 * FX_PI; + } + a2 -= da / 4; + a1 += da; + while(a1 < a2) { + out_vertices.add(coord_type(x + FXSYS_Mul(width, FXSYS_cos(a1)), + y + FXSYS_Mul(width, FXSYS_sin(a1)))); + a1 += da; + } + } else { + if(a1 < a2) { + a2 -= 2 * FX_PI; + } + a2 += da / 4; + a1 -= da; + while(a1 > a2) { + out_vertices.add(coord_type(x + FXSYS_Mul(width, FXSYS_cos(a1)), + y + FXSYS_Mul(width, FXSYS_sin(a1)))); + a1 -= da; + } + } + out_vertices.add(coord_type(x + dx2, y + dy2)); +} +template +void stroke_calc_miter(VertexConsumer& out_vertices, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + FX_FLOAT dx1, FX_FLOAT dy1, + FX_FLOAT dx2, FX_FLOAT dy2, + FX_FLOAT width, + line_join_e line_join, + FX_FLOAT miter_limit, + FX_FLOAT approximation_scale) +{ + typedef typename VertexConsumer::value_type coord_type; + FX_FLOAT xi = v1.x; + FX_FLOAT yi = v1.y; + bool miter_limit_exceeded = true; + 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)) { + FX_FLOAT d1 = calc_distance(v1.x, v1.y, xi, yi); + FX_FLOAT lim = FXSYS_Mul(width, miter_limit); + if(d1 <= lim) { + out_vertices.add(coord_type(xi, yi)); + miter_limit_exceeded = false; + } + } else { + FX_FLOAT x2 = v1.x + dx1; + FX_FLOAT y2 = v1.y - dy1; + if((FXSYS_Mul(x2 - v0.x, dy1) - FXSYS_Mul(v0.y - y2, dx1) < 0) != + (FXSYS_Mul(x2 - v2.x, dy1) - FXSYS_Mul(v2.y - y2, dx1) < 0)) { + out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); + miter_limit_exceeded = false; + } + } + if(miter_limit_exceeded) { + switch(line_join) { + case miter_join_revert: + 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: + stroke_calc_arc(out_vertices, + v1.x, v1.y, dx1, -dy1, dx2, -dy2, + width, approximation_scale); + break; + default: + out_vertices.add(coord_type(v1.x + dx1 + FXSYS_Mul(dy1, miter_limit), + v1.y - dy1 + FXSYS_Mul(dx1, miter_limit))); + out_vertices.add(coord_type(v1.x + dx2 - FXSYS_Mul(dy2, miter_limit), + v1.y - dy2 - FXSYS_Mul(dx2, miter_limit))); + break; + } + } +} +template +void stroke_calc_cap(VertexConsumer& out_vertices, + const vertex_dist& v0, + const vertex_dist& v1, + FX_FLOAT len, + line_cap_e line_cap, + FX_FLOAT width, + FX_FLOAT approximation_scale) +{ + typedef typename VertexConsumer::value_type coord_type; + out_vertices.remove_all(); + FX_FLOAT dx1 = FXSYS_Div(v1.y - v0.y, len); + FX_FLOAT dy1 = FXSYS_Div(v1.x - v0.x, len); + FX_FLOAT dx2 = 0; + FX_FLOAT dy2 = 0; + dx1 = FXSYS_Mul(dx1, width); + dy1 = FXSYS_Mul(dy1, width); + if(line_cap != round_cap) { + if(line_cap == square_cap) { + dx2 = dy1; + dy2 = dx1; + } + 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 { + FX_FLOAT a1 = FXSYS_atan2(dy1, -dx1); + FX_FLOAT a2 = a1 + FX_PI; + FX_FLOAT da = FXSYS_acos(FXSYS_Div(width, width + + FXSYS_Div(1.0f / 8, approximation_scale))) * 2; + out_vertices.add(coord_type(v0.x - dx1, v0.y + dy1)); + a1 += da; + a2 -= da / 4; + while(a1 < a2) { + out_vertices.add(coord_type(v0.x + FXSYS_Mul(width, FXSYS_cos(a1)), + v0.y + FXSYS_Mul(width, FXSYS_sin(a1)))); + a1 += da; + } + out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1)); + } +} +template +void stroke_calc_join(VertexConsumer& out_vertices, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + FX_FLOAT len1, + FX_FLOAT len2, + FX_FLOAT width, + line_join_e line_join, + inner_join_e inner_join, + FX_FLOAT miter_limit, + FX_FLOAT inner_miter_limit, + FX_FLOAT approximation_scale) +{ + typedef typename VertexConsumer::value_type coord_type; + FX_FLOAT dx1, dy1, dx2, dy2; + dx1 = FXSYS_MulDiv(width, v1.y - v0.y, len1); + dy1 = FXSYS_MulDiv(width, v1.x - v0.x, len1); + dx2 = FXSYS_MulDiv(width, v2.y - v1.y, len2); + dy2 = FXSYS_MulDiv(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) { + switch(inner_join) { + default: + 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: + stroke_calc_miter(out_vertices, + v0, v1, v2, dx1, dy1, dx2, dy2, + width, + miter_join_revert, + inner_miter_limit, + 1.0f); + break; + case inner_jag: + case inner_round: { + FX_FLOAT d = (dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2); + if(d < len1 * len1 && d < len2 * len2) { + stroke_calc_miter(out_vertices, + v0, v1, v2, dx1, dy1, dx2, dy2, + width, + miter_join_revert, + inner_miter_limit, + 1.0f); + } else { + if(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 )); + stroke_calc_arc(out_vertices, + v1.x, v1.y, dx2, -dy2, dx1, -dy1, + width, approximation_scale); + out_vertices.add(coord_type(v1.x, v1.y )); + out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); + } + } + } + break; + } + } else { + switch(line_join) { + case miter_join: + case miter_join_revert: + case miter_join_round: + stroke_calc_miter(out_vertices, + v0, v1, v2, dx1, dy1, dx2, dy2, + width, + line_join, + miter_limit, + approximation_scale); + break; + case round_join: + stroke_calc_arc(out_vertices, + v1.x, v1.y, dx1, -dy1, dx2, -dy2, + width, approximation_scale); + break; + default: + out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); + out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); + break; + } + } +} +} +#endif diff --git a/third_party/agg23/agg_path_storage.cpp b/third_party/agg23/agg_path_storage.cpp new file mode 100644 index 0000000000..f5c9843e58 --- /dev/null +++ b/third_party/agg23/agg_path_storage.cpp @@ -0,0 +1,98 @@ + +//---------------------------------------------------------------------------- +// XYQ: 2006-01-22 Copied from AGG project. +// TODO: This file uses intensive floating point operations, so it's NOT suitable +// for platforms like Symbian OS. We need to change to FIX format. +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Class path_storage +// +//---------------------------------------------------------------------------- +#include "../../core/include/fxcrt/fx_basic.h" +#include "agg_path_storage.h" +#include "agg_math.h" +namespace agg +{ +path_storage::~path_storage() +{ + if(m_total_blocks) { + FX_FLOAT** coord_blk = m_coord_blocks + m_total_blocks - 1; + while(m_total_blocks--) { + FX_Free(*coord_blk); + --coord_blk; + } + FX_Free(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) +{ +} +void path_storage::allocate_block(unsigned nb) +{ + if(nb >= m_max_blocks) { + FX_FLOAT** new_coords = + FX_Alloc2D(FX_FLOAT*, m_max_blocks + block_pool, 2); + unsigned char** new_cmds = + (unsigned char**)(new_coords + m_max_blocks + block_pool); + if(m_coord_blocks) { + FXSYS_memcpy(new_coords, + m_coord_blocks, + m_max_blocks * sizeof(FX_FLOAT*)); + FXSYS_memcpy(new_cmds, + m_cmd_blocks, + m_max_blocks * sizeof(unsigned char*)); + FX_Free(m_coord_blocks); + } + m_coord_blocks = new_coords; + m_cmd_blocks = new_cmds; + m_max_blocks += block_pool; + } + m_coord_blocks[nb] = + FX_Alloc( FX_FLOAT, block_size * 2 + + block_size / + (sizeof(FX_FLOAT) / 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::curve4(FX_FLOAT x_ctrl1, FX_FLOAT y_ctrl1, + FX_FLOAT x_ctrl2, FX_FLOAT y_ctrl2, + FX_FLOAT x_to, FX_FLOAT 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::end_poly() +{ + if(m_total_vertices) { + if(is_vertex(command(m_total_vertices - 1))) { + add_vertex(0, 0, path_cmd_end_poly | path_flags_close); + } + } +} +} diff --git a/third_party/agg23/agg_path_storage.h b/third_party/agg23/agg_path_storage.h new file mode 100644 index 0000000000..dc13851d09 --- /dev/null +++ b/third_party/agg23/agg_path_storage.h @@ -0,0 +1,172 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_PATH_STORAGE_INCLUDED +#define AGG_PATH_STORAGE_INCLUDED +#include "agg_basics.h" +namespace agg +{ +class path_storage +{ + enum block_scale_e { + block_shift = 8, + block_size = 1 << block_shift, + block_mask = block_size - 1, + block_pool = 256 + }; +public: + class vertex_source + { + public: + vertex_source() {} + vertex_source(const path_storage& p) : m_path(&p), m_vertex_idx(0) {} + void rewind(unsigned path_id) + { + m_vertex_idx = path_id; + } + unsigned vertex(FX_FLOAT* x, FX_FLOAT* y) + { + return (m_vertex_idx < m_path->total_vertices()) ? + m_path->vertex(m_vertex_idx++, x, y) : + path_cmd_stop; + } + private: + const path_storage* m_path; + unsigned m_vertex_idx; + }; + ~path_storage(); + path_storage(); + unsigned last_vertex(FX_FLOAT* x, FX_FLOAT* y) const; + unsigned prev_vertex(FX_FLOAT* x, FX_FLOAT* y) const; + void move_to(FX_FLOAT x, FX_FLOAT y); + void line_to(FX_FLOAT x, FX_FLOAT y); + void curve4(FX_FLOAT x_ctrl1, FX_FLOAT y_ctrl1, + FX_FLOAT x_ctrl2, FX_FLOAT y_ctrl2, + FX_FLOAT x_to, FX_FLOAT y_to); + template + void add_path(VertexSource& vs, + unsigned path_id = 0, + bool solid_path = true) + { + FX_FLOAT 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); + } + } + template + void add_path_curve(VertexSource& vs, + unsigned path_id = 0, + bool solid_path = true) + { + FX_FLOAT x, y; + unsigned cmd; + int flag; + vs.rewind(path_id); + while(!is_stop(cmd = vs.vertex_curve_flag(&x, &y, flag))) { + if(is_move_to(cmd) && solid_path && m_total_vertices) { + cmd = path_cmd_line_to | flag; + } + add_vertex(x, y, cmd | flag); + } + } + unsigned total_vertices() const + { + return m_total_vertices; + } + unsigned vertex(unsigned idx, FX_FLOAT* x, FX_FLOAT* y) const + { + unsigned nb = idx >> block_shift; + const FX_FLOAT* 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]; + } + unsigned getflag(unsigned idx) const + { + return m_cmd_blocks[idx >> block_shift][idx & block_mask] & path_flags_jr; + } + void rewind(unsigned path_id); + unsigned vertex(FX_FLOAT* x, FX_FLOAT* y); + void add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd); + void end_poly(); +private: + void allocate_block(unsigned nb); + unsigned char* storage_ptrs(FX_FLOAT** xy_ptr); +private: + unsigned m_total_vertices; + unsigned m_total_blocks; + unsigned m_max_blocks; + FX_FLOAT** m_coord_blocks; + unsigned char** m_cmd_blocks; + unsigned m_iterator; +}; +inline unsigned path_storage::vertex(FX_FLOAT* x, FX_FLOAT* y) +{ + if(m_iterator >= m_total_vertices) { + return path_cmd_stop; + } + return vertex(m_iterator++, x, y); +} +inline unsigned path_storage::prev_vertex(FX_FLOAT* x, FX_FLOAT* y) const +{ + if(m_total_vertices > 1) { + return vertex(m_total_vertices - 2, x, y); + } + return path_cmd_stop; +} +inline unsigned path_storage::last_vertex(FX_FLOAT* x, FX_FLOAT* y) const +{ + if(m_total_vertices) { + return vertex(m_total_vertices - 1, x, y); + } + return path_cmd_stop; +} +inline unsigned char* path_storage::storage_ptrs(FX_FLOAT** 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); +} +inline void path_storage::add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd) +{ + FX_FLOAT* 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(FX_FLOAT x, FX_FLOAT y) +{ + add_vertex(x, y, path_cmd_move_to); +} +inline void path_storage::line_to(FX_FLOAT x, FX_FLOAT y) +{ + add_vertex(x, y, path_cmd_line_to); +} +} +#endif diff --git a/third_party/agg23/agg_pixfmt_gray.h b/third_party/agg23/agg_pixfmt_gray.h new file mode 100644 index 0000000000..5a80935479 --- /dev/null +++ b/third_party/agg23/agg_pixfmt_gray.h @@ -0,0 +1,177 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// 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 "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_rendering_buffer.h" +namespace agg +{ +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); + } +}; +template +class pixel_formats_gray +{ +public: + typedef rendering_buffer::row_data row_data; + typedef rendering_buffer::span_data span_data; + typedef typename Blender::color_type 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, + base_size = color_type::base_size, + base_mask = color_type::base_mask + }; +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: + pixel_formats_gray(rendering_buffer& rb) : + m_rbuf(&rb) + {} + AGG_INLINE unsigned width() const + { + return m_rbuf->width(); + } + AGG_INLINE unsigned height() const + { + return m_rbuf->height(); + } + AGG_INLINE color_type pixel(int x, int y) const + { + value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset; + return color_type(*p); + } + row_data row(int x, int y) const + { + return row_data(x, + width() - 1, + m_rbuf->row(y) + + x * Step * sizeof(value_type) + + Offset * sizeof(value_type)); + } + span_data span(int x, int y, unsigned len) + { + return span_data(x, len, + m_rbuf->row(y) + + x * Step * sizeof(value_type) + + Offset * sizeof(value_type)); + } + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + *((value_type*)m_rbuf->row(y) + 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(y) + 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(y) + x * Step + Offset; + do { + *p = c.v; + p += Step; + } 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(y) + 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_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(y) + 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); + } + } +private: + rendering_buffer* m_rbuf; +}; +typedef blender_gray blender_gray8; +typedef pixel_formats_gray pixfmt_gray8; +} +#endif diff --git a/third_party/agg23/agg_rasterizer_scanline_aa.cpp b/third_party/agg23/agg_rasterizer_scanline_aa.cpp new file mode 100644 index 0000000000..8216e60221 --- /dev/null +++ b/third_party/agg23/agg_rasterizer_scanline_aa.cpp @@ -0,0 +1,489 @@ + +//---------------------------------------------------------------------------- +// XYQ: 2006-01-22 Copied from AGG project. +// This file uses only integer data, so it's suitable for all platforms. +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// +// 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 "../../core/include/fxcrt/fx_ext.h" +#include +#include "agg_rasterizer_scanline_aa.h" +namespace agg +{ +AGG_INLINE void cell_aa::set_cover(int c, int a) +{ + cover = c; + area = a; +} +AGG_INLINE void cell_aa::add_cover(int c, int a) +{ + cover += c; + area += a; +} +AGG_INLINE void cell_aa::set_coord(int cx, int cy) +{ + x = cx; + y = cy; +} +AGG_INLINE void cell_aa::set(int cx, int cy, int c, int a) +{ + x = cx; + y = cy; + cover = c; + area = a; +} +outline_aa::~outline_aa() +{ + if(m_num_blocks) { + cell_aa** ptr = m_cells + m_num_blocks - 1; + while(m_num_blocks--) { + FX_Free(*ptr); + ptr--; + } + FX_Free(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_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 = FX_Alloc( cell_aa*, m_max_blocks + cell_block_pool); + if(m_cells) { + FXSYS_memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_aa*)); + FX_Free(m_cells); + } + m_cells = new_cells; + m_max_blocks += cell_block_pool; + } + m_cells[m_num_blocks++] = FX_Alloc(cell_aa, cell_block_size); + } + m_cur_cell_ptr = m_cells[m_cur_block++]; +} +AGG_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; + } +} +AGG_INLINE void outline_aa::set_cur_cell(int x, int y) +{ + if(m_cur_cell.x != x || m_cur_cell.y != y) { + add_cur_cell(); + m_cur_cell.set(x, y, 0, 0); + if(x < m_min_x) { + m_min_x = x; + } + if(x > m_max_x) { + m_max_x = x; + } + if(y < m_min_y) { + m_min_y = y; + } + if(y > m_max_y) { + m_max_y = y; + } + } +} +AGG_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; + if(y1 == y2) { + set_cur_cell(ex2, ey); + return; + } + if(ex1 == ex2) { + delta = y2 - y1; + m_cur_cell.add_cover(delta, (fx1 + fx2) * delta); + return; + } + 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) +{ + enum dx_limit_e { dx_limit = 16384 << poly_base_shift }; + int dx = x2 - x1; + if(dx >= dx_limit || dx <= -dx_limit) { + int cx = (x1 + x2) >> 1; + int cy = (y1 + y2) >> 1; + render_line(x1, y1, cx, cy); + render_line(cx, cy, x2, y2); + } + int dy = y2 - y1; + 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 x_from, x_to; + int p, rem, mod, lift, delta, first, incr; + if(ey1 == ey2) { + render_hline(ey1, x1, fy1, x2, fy2); + return; + } + 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; + 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) { + m_cur_cell.set_cover(delta, area); + ey1 += incr; + set_cur_cell(ex, ey1); + } + delta = fy2 - poly_base_size + first; + m_cur_cell.add_cover(delta, two_fx * delta); + return; + } + 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; +} +template static AGG_INLINE void swap_cells(T* a, T* b) +{ + T temp = *a; + *a = *b; + *b = temp; +} +enum { + qsort_threshold = 9 +}; +static void 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) { + pivot = base + len / 2; + swap_cells(base, pivot); + i = base + 1; + j = limit - 1; + 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); + 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 { + 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; + } + } + } +} +void outline_aa::sort_cells() +{ + if(m_sorted) { + return; + } + add_cur_cell(); + if(m_num_cells == 0) { + return; + } + m_sorted_cells.allocate(m_num_cells, 16); + if (m_max_y > 0 && m_min_y < 0 && -m_min_y > INT_MAX - m_max_y) { + return; + } + unsigned size = m_max_y - m_min_y; + if (size + 1 < size) { + return; + } + size++; + m_sorted_y.allocate(size, 16); + m_sorted_y.zero(); + cell_aa** block_ptr = m_cells; + cell_aa* cell_ptr = NULL; + 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; + } + } + i = m_num_cells & cell_block_mask; + if (i) { + cell_ptr = *block_ptr++; + } + while(i--) { + m_sorted_y[cell_ptr->y - m_min_y].start++; + ++cell_ptr; + } + 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; + } + 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& cur_y = m_sorted_y[cell_ptr->y - m_min_y]; + m_sorted_cells[cur_y.start + cur_y.num] = cell_ptr; + ++cur_y.num; + ++cell_ptr; + } + } + i = m_num_cells & cell_block_mask; + if (i) { + cell_ptr = *block_ptr++; + } + while(i--) { + sorted_y& cur_y = m_sorted_y[cell_ptr->y - m_min_y]; + m_sorted_cells[cur_y.start + cur_y.num] = cell_ptr; + ++cur_y.num; + ++cell_ptr; + } + for(i = 0; i < m_sorted_y.size(); i++) { + const sorted_y& cur_y = m_sorted_y[i]; + if(cur_y.num) { + qsort_cells(m_sorted_cells.data() + cur_y.start, cur_y.num); + } + } + m_sorted = true; +} +} diff --git a/third_party/agg23/agg_rasterizer_scanline_aa.h b/third_party/agg23/agg_rasterizer_scanline_aa.h new file mode 100644 index 0000000000..da1900d0dd --- /dev/null +++ b/third_party/agg23/agg_rasterizer_scanline_aa.h @@ -0,0 +1,472 @@ + +//---------------------------------------------------------------------------- +// 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_SCANLINE_AA_INCLUDED +#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED +#include "../../core/include/fxge/fx_ge.h" +#include "agg_basics.h" +#include "agg_math.h" +#include "agg_array.h" +#include "agg_clip_liang_barsky.h" +#include "agg_render_scanlines.h" +namespace agg +{ +enum poly_base_scale_e { + poly_base_shift = 8, + poly_base_size = 1 << poly_base_shift, + poly_base_mask = poly_base_size - 1 +}; +inline int poly_coord(FX_FLOAT c) +{ + return int(c * poly_base_size); +} +struct cell_aa { + 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); +}; +class outline_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: + ~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; + } + 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_aa* 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: + 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 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(); +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; + pod_array m_sorted_cells; + pod_array m_sorted_y; + 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; +}; +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; +}; +enum filling_rule_e { + fill_non_zero, + fill_even_odd +}; +class rasterizer_scanline_aa +{ + enum status { + status_initial, + status_line_to, + status_closed + }; +public: + enum aa_scale_e { + aa_num = 1 << 8, + aa_mask = aa_num - 1, + aa_2num = aa_num * 2, + aa_2mask = aa_2num - 1 + }; + rasterizer_scanline_aa() : + m_filling_rule(fill_non_zero), + m_clipped_start_x(0), + m_clipped_start_y(0), + m_status(status_initial), + m_clipping(false) + { + } + ~rasterizer_scanline_aa() {} + void filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + 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(); + } + void reset() + { + m_outline.reset(); + m_status = status_initial; + } + void clip_box(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) + { + m_clip_box = rect(poly_coord(x1), poly_coord(y1), + poly_coord(x2), poly_coord(y2)); + m_clip_box.normalize(); + m_clipping = true; + } + void add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd) + { + 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)); + } + } + } + } + void 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); + } + } + void line_to(int x, int y) + { + if(m_clipping) { + clip_segment(x, y); + } else { + line_to_no_clip(x, y); + } + } + void close_polygon() + { + if (m_status != status_line_to) { + return; + } + if(m_clipping) { + clip_segment(m_start_x, m_start_y); + } + close_polygon_no_clip(); + } + AGG_INLINE unsigned calculate_alpha(int area, bool no_smooth) const + { + int cover = area >> (poly_base_shift * 2 + 1 - 8); + if(cover < 0) { + cover = -cover; + } + if(m_filling_rule == fill_even_odd) { + cover &= aa_2mask; + if(cover > aa_num) { + cover = aa_2num - cover; + } + } + if (no_smooth) { + cover = cover > aa_mask / 2 ? aa_mask : 0; + } + if(cover > aa_mask) { + cover = aa_mask; + } + return cover; + } + AGG_INLINE void sort() + { + m_outline.sort_cells(); + } + AGG_INLINE bool rewind_scanlines() + { + close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0) { + return false; + } + m_cur_y = m_outline.min_y(); + return true; + } + AGG_INLINE bool navigate_scanline(int y) + { + 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_cur_y = y; + return true; + } + template bool sweep_scanline(Scanline& sl, bool no_smooth) + { + for(;;) { + if(m_cur_y > m_outline.max_y()) { + return false; + } + sl.reset_spans(); + unsigned num_cells = m_outline.scanline_num_cells(m_cur_y); + const cell_aa* const* cells = m_outline.scanline_cells(m_cur_y); + int cover = 0; + while(num_cells) { + const cell_aa* cur_cell = *cells; + int x = cur_cell->x; + int area = cur_cell->area; + unsigned alpha; + cover += cur_cell->cover; + while(--num_cells) { + cur_cell = *++cells; + if(cur_cell->x != x) { + break; + } + area += cur_cell->area; + cover += cur_cell->cover; + } + if(area) { + alpha = calculate_alpha((cover << (poly_base_shift + 1)) - area, no_smooth); + if(alpha) { + sl.add_cell(x, alpha); + } + x++; + } + if(num_cells && cur_cell->x > x) { + alpha = calculate_alpha(cover << (poly_base_shift + 1), no_smooth); + if(alpha) { + sl.add_span(x, cur_cell->x - x, alpha); + } + } + } + if(sl.num_spans()) { + break; + } + ++m_cur_y; + } + sl.finalize(m_cur_y); + ++m_cur_y; + return true; + } + template + void add_path(VertexSource& vs, unsigned path_id = 0) + { + FX_FLOAT x; + FX_FLOAT y; + unsigned cmd; + vs.rewind(path_id); + while(!is_stop(cmd = vs.vertex(&x, &y))) { + add_vertex(x, y, cmd); + } + } + template + void add_path_transformed(VertexSource& vs, const CFX_AffineMatrix* pMatrix, unsigned path_id = 0) + { + FX_FLOAT x; + FX_FLOAT y; + unsigned cmd; + vs.rewind(path_id); + while(!is_stop(cmd = vs.vertex(&x, &y))) { + if (pMatrix) { + pMatrix->Transform(x, y); + } + add_vertex(x, y, cmd); + } + } +private: + 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) + { + if(m_status == status_line_to) { + close_polygon_no_clip(); + } + m_outline.move_to(x * 1, y); + m_clipped_start_x = x; + m_clipped_start_y = y; + m_status = status_line_to; + } + void line_to_no_clip(int x, int y) + { + if(m_status != status_initial) { + m_outline.line_to(x * 1, y); + m_status = status_line_to; + } + } + void close_polygon_no_clip() + { + if(m_status == status_line_to) { + m_outline.line_to(m_clipped_start_x * 1, m_clipped_start_y); + m_status = status_closed; + } + } + void clip_segment(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; + } +private: + outline_aa m_outline; + 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; + unsigned m_status; + rect m_clip_box; + bool m_clipping; + int m_cur_y; +}; +} +#endif diff --git a/third_party/agg23/agg_render_scanlines.h b/third_party/agg23/agg_render_scanlines.h new file mode 100644 index 0000000000..0dfd6d259f --- /dev/null +++ b/third_party/agg23/agg_render_scanlines.h @@ -0,0 +1,50 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// 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 +{ +template +void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren, bool no_smooth) +{ + 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, no_smooth)) { + ren.render(sl); + } + } +} +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); + } +} +} +#endif diff --git a/third_party/agg23/agg_renderer_base.h b/third_party/agg23/agg_renderer_base.h new file mode 100644 index 0000000000..bd1b203b9a --- /dev/null +++ b/third_party/agg23/agg_renderer_base.h @@ -0,0 +1,163 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// class renderer_base +// +//---------------------------------------------------------------------------- +#ifndef AGG_RENDERER_BASE_INCLUDED +#define AGG_RENDERER_BASE_INCLUDED +#include "agg_basics.h" +#include "agg_rendering_buffer.h" +namespace agg +{ +template class renderer_base +{ +public: + typedef PixelFormat pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::row_data row_data; + typedef typename pixfmt_type::span_data span_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(0, 0, ren.width() - 1, ren.height() - 1); + } + const pixfmt_type& ren() const + { + return *m_ren; + } + pixfmt_type& ren() + { + return *m_ren; + } + unsigned width() const + { + return m_ren->width(); + } + unsigned height() const + { + return m_ren->height(); + } + 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& 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 blend_hline(int x1, int y, int x2, + const color_type& c, cover_type cover) + { + if(x1 > x2) { + int t = x2; + x2 = x1; + x1 = t; + } + if(y > ymax()) { + return; + } + if(y < ymin()) { + return; + } + if(x1 > xmax()) { + return; + } + if(x2 < xmin()) { + return; + } + if(x1 < xmin()) { + x1 = xmin(); + } + if(x2 > xmax()) { + x2 = xmax(); + } + m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover); + } + void blend_solid_hspan(int x, int y, int len, + const color_type& c, + const cover_type* covers) + { + if(y > ymax()) { + return; + } + if(y < ymin()) { + return; + } + if(x < xmin()) { + len -= xmin() - x; + if(len <= 0) { + return; + } + covers += xmin() - x; + x = xmin(); + } + if(x + len > xmax()) { + len = xmax() - x + 1; + if(len <= 0) { + return; + } + } + m_ren->blend_solid_hspan(x, y, len, c, covers); + } +private: + pixfmt_type* m_ren; + rect m_clip_box; +}; +} +#endif diff --git a/third_party/agg23/agg_renderer_scanline.h b/third_party/agg23/agg_renderer_scanline.h new file mode 100644 index 0000000000..62d104f7f2 --- /dev/null +++ b/third_party/agg23/agg_renderer_scanline.h @@ -0,0 +1,93 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_RENDERER_SCANLINE_INCLUDED +#define AGG_RENDERER_SCANLINE_INCLUDED +#include "agg_basics.h" +#include "agg_renderer_base.h" +#include "agg_render_scanlines.h" +namespace agg +{ +template class renderer_scanline_aa +{ +public: + typedef BaseRenderer base_ren_type; + typedef SpanGenerator span_gen_type; + renderer_scanline_aa() : m_ren(0), m_span_gen(0) {} + renderer_scanline_aa(base_ren_type& ren, span_gen_type& span_gen) : + m_ren(&ren), + m_span_gen(&span_gen) + {} + void attach(base_ren_type& ren, span_gen_type& span_gen) + { + m_ren = &ren; + m_span_gen = &span_gen; + } + 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 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(); + for(;;) { + 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); + } + } + if(--num_spans == 0) { + break; + } + ++span; + } + } + } while(m_ren->next_clip_box()); + } +private: + base_ren_type* m_ren; + SpanGenerator* m_span_gen; +}; +} +#endif diff --git a/third_party/agg23/agg_rendering_buffer.h b/third_party/agg23/agg_rendering_buffer.h new file mode 100644 index 0000000000..9c1c0c6899 --- /dev/null +++ b/third_party/agg23/agg_rendering_buffer.h @@ -0,0 +1,145 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// class rendering_buffer +// +//---------------------------------------------------------------------------- +#ifndef AGG_RENDERING_BUFFER_INCLUDED +#define AGG_RENDERING_BUFFER_INCLUDED +#include "agg_basics.h" +namespace agg +{ +class rendering_buffer +{ +public: + struct row_data { + int x1, x2; + const int8u* ptr; + row_data() {} + row_data(int x1_, int x2_, const int8u* ptr_) : + x1(x1_), x2(x2_), ptr(ptr_) {} + }; + struct span_data { + int x; + unsigned len; + int8u* ptr; + span_data() {} + span_data(int) : x(0), len(0), ptr(0) {} + span_data(int x_, unsigned len_, int8u* ptr_) : + x(x_), len(len_), ptr(ptr_) {} + }; + ~rendering_buffer() + { + FX_Free(m_rows); + } + rendering_buffer() : + m_buf(0), + m_rows(0), + m_width(0), + m_height(0), + m_stride(0), + m_max_height(0) + { + } + rendering_buffer(int8u* buf, unsigned width, unsigned height, int stride) : + m_buf(0), + m_rows(0), + m_width(0), + m_height(0), + m_stride(0), + m_max_height(0) + { + attach(buf, width, height, stride); + } + void attach(int8u* buf, unsigned width, unsigned height, int stride) + { + m_buf = buf; + m_width = width; + m_height = height; + m_stride = stride; + if(height > m_max_height) { + FX_Free(m_rows); + m_rows = FX_Alloc(int8u*, m_max_height = height); + } + int8u* row_ptr = m_buf; + if(stride < 0) { + row_ptr = m_buf - int(height - 1) * stride; + } + int8u** rows = m_rows; + while(height--) { + *rows++ = row_ptr; + row_ptr += stride; + } + } + int8u* buf() + { + return m_buf; + } + const int8u* 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); + } + int8u* row(unsigned y) + { + return m_rows[y]; + } + const int8u* row(unsigned y) const + { + return m_rows[y]; + } + int8u* next_row(void* p) + { + return (int8u*)p + m_stride; + } + const int8u* next_row(const void* p) const + { + return (int8u*)p + m_stride; + } + int8u const* const* rows() const + { + return m_rows; + } +private: + rendering_buffer(const rendering_buffer&); + const rendering_buffer& operator = (const rendering_buffer&); +private: + int8u* m_buf; + int8u** m_rows; + unsigned m_width; + unsigned m_height; + int m_stride; + unsigned m_max_height; +}; +} +#endif diff --git a/third_party/agg23/agg_scanline_u.h b/third_party/agg23/agg_scanline_u.h new file mode 100644 index 0000000000..2100115329 --- /dev/null +++ b/third_party/agg23/agg_scanline_u.h @@ -0,0 +1,150 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// 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 "agg_array.h" +namespace agg +{ +template class scanline_u +{ +public: + typedef scanline_u self_type; + typedef CoverT cover_type; + typedef int16 coord_type; + struct span { + coord_type x; + coord_type len; + cover_type* covers; + }; + typedef span* iterator; + typedef const span* const_iterator; + ~scanline_u() + { + FX_Free(m_spans); + FX_Free(m_covers); + } + scanline_u() : + m_min_x(0), + m_max_len(0), + m_last_x(0x7FFFFFF0), + m_covers(0), + m_spans(0), + m_cur_span(0) + {} + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 2; + if(max_len > m_max_len) { + FX_Free(m_spans); + FX_Free(m_covers); + m_covers = FX_Alloc( cover_type , max_len); + m_spans = FX_Alloc( span , max_len); + m_max_len = max_len; + } + m_last_x = 0x7FFFFFF0; + m_min_x = min_x; + m_cur_span = m_spans; + } + 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 CoverT* covers) + { + x -= m_min_x; + FXSYS_memcpy(m_covers + x, covers, len * sizeof(CoverT)); + 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; + FXSYS_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; + } + 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; + } +private: + scanline_u(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; +}; +typedef scanline_u scanline_u8; +} +#endif diff --git a/third_party/agg23/agg_shorten_path.h b/third_party/agg23/agg_shorten_path.h new file mode 100644 index 0000000000..d7eb4be018 --- /dev/null +++ b/third_party/agg23/agg_shorten_path.h @@ -0,0 +1,57 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_SHORTEN_PATH_INCLUDED +#define AGG_SHORTEN_PATH_INCLUDED +#include "agg_basics.h" +#include "agg_vertex_sequence.h" +namespace agg +{ +template +void shorten_path(VertexSequence& vs, FX_FLOAT s, unsigned closed = 0) +{ + typedef typename VertexSequence::value_type vertex_type; + if(s > 0 && vs.size() > 1) { + FX_FLOAT d; + int n = int(vs.size() - 2); + while(n) { + d = vs[n].dist; + if(d > s) { + break; + } + vs.remove_last(); + s -= d; + --n; + } + if(vs.size() < 2) { + vs.remove_all(); + } else { + n = vs.size() - 1; + vertex_type& prev = vs[n - 1]; + vertex_type& last = vs[n]; + d = (prev.dist - s) / prev.dist; + FX_FLOAT x = prev.x + (last.x - prev.x) * d; + FX_FLOAT y = prev.y + (last.y - prev.y) * d; + last.x = x; + last.y = y; + if(!prev(last)) { + vs.remove_last(); + } + vs.close(closed != 0); + } + } +} +} +#endif diff --git a/third_party/agg23/agg_vcgen_dash.cpp b/third_party/agg23/agg_vcgen_dash.cpp new file mode 100644 index 0000000000..43f8edf350 --- /dev/null +++ b/third_party/agg23/agg_vcgen_dash.cpp @@ -0,0 +1,176 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Line dash generator +// +//---------------------------------------------------------------------------- +#include "../../core/include/fxcrt/fx_basic.h" +#include "agg_vcgen_dash.h" +#include "agg_shorten_path.h" +namespace agg +{ +vcgen_dash::vcgen_dash() : + m_total_dash_len(0), + m_num_dashes(0), + m_dash_start(0), + m_shorten(0), + m_curr_dash_start(0), + m_curr_dash(0), + m_src_vertices(), + m_closed(0), + m_status(initial), + m_src_vertex(0) +{ +} +void vcgen_dash::remove_all_dashes() +{ + m_total_dash_len = 0; + m_num_dashes = 0; + m_curr_dash_start = 0; + m_curr_dash = 0; +} +void vcgen_dash::add_dash(FX_FLOAT dash_len, FX_FLOAT gap_len) +{ + if(m_num_dashes < max_dashes) { + m_total_dash_len += dash_len + gap_len; + m_dashes[m_num_dashes++] = dash_len; + m_dashes[m_num_dashes++] = gap_len; + } +} +void vcgen_dash::dash_start(FX_FLOAT ds) +{ + m_dash_start = ds; + calc_dash_start(FXSYS_fabs(ds)); +} +void vcgen_dash::calc_dash_start(FX_FLOAT ds) +{ + m_curr_dash = 0; + m_curr_dash_start = 0; + while(ds > 0) { + if(ds > m_dashes[m_curr_dash]) { + ds -= m_dashes[m_curr_dash]; + ++m_curr_dash; + m_curr_dash_start = 0; + if(m_curr_dash >= m_num_dashes) { + m_curr_dash = 0; + } + } else { + m_curr_dash_start = ds; + ds = 0; + } + } +} +void vcgen_dash::remove_all() +{ + m_status = initial; + m_src_vertices.remove_all(); + m_closed = 0; +} +void vcgen_dash::add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd) +{ + m_status = initial; + if(is_move_to(cmd)) { + m_src_vertices.modify_last(vertex_dist(x, y)); + } else { + if(is_vertex(cmd)) { + m_src_vertices.add(vertex_dist(x, y)); + } else { + m_closed = get_close_flag(cmd); + } + } +} +void vcgen_dash::rewind(unsigned) +{ + if(m_status == initial) { + m_src_vertices.close(m_closed != 0); + shorten_path(m_src_vertices, m_shorten, m_closed); + } + m_status = ready; + m_src_vertex = 0; +} +unsigned vcgen_dash::vertex(FX_FLOAT* x, FX_FLOAT* y) +{ + unsigned cmd = path_cmd_move_to; + while(!is_stop(cmd)) { + switch(m_status) { + case initial: + rewind(0); + case ready: + if(m_num_dashes < 2 || m_src_vertices.size() < 2) { + cmd = path_cmd_stop; + break; + } + m_status = polyline; + m_src_vertex = 1; + m_v1 = &m_src_vertices[0]; + m_v2 = &m_src_vertices[1]; + m_curr_rest = m_v1->dist; + *x = m_v1->x; + *y = m_v1->y; + if(m_dash_start >= 0) { + calc_dash_start(m_dash_start); + } + return path_cmd_move_to; + case polyline: { + FX_FLOAT dash_rest = m_dashes[m_curr_dash] - m_curr_dash_start; + unsigned cmd = (m_curr_dash & 1) ? + path_cmd_move_to : + path_cmd_line_to; + if(m_curr_rest > dash_rest) { + m_curr_rest -= dash_rest; + ++m_curr_dash; + if(m_curr_dash >= m_num_dashes) { + m_curr_dash = 0; + } + m_curr_dash_start = 0; + *x = m_v2->x - (m_v2->x - m_v1->x) * m_curr_rest / m_v1->dist; + *y = m_v2->y - (m_v2->y - m_v1->y) * m_curr_rest / m_v1->dist; + } else { + m_curr_dash_start += m_curr_rest; + *x = m_v2->x; + *y = m_v2->y; + ++m_src_vertex; + m_v1 = m_v2; + m_curr_rest = m_v1->dist; + if(m_closed) { + if(m_src_vertex > m_src_vertices.size()) { + m_status = stop; + } else { + m_v2 = &m_src_vertices + [ + (m_src_vertex >= m_src_vertices.size()) ? 0 : + m_src_vertex + ]; + } + } else { + if(m_src_vertex >= m_src_vertices.size()) { + m_status = stop; + } else { + m_v2 = &m_src_vertices[m_src_vertex]; + } + } + } + return cmd; + } + break; + case stop: + cmd = path_cmd_stop; + break; + } + } + return path_cmd_stop; +} +} diff --git a/third_party/agg23/agg_vcgen_dash.h b/third_party/agg23/agg_vcgen_dash.h new file mode 100644 index 0000000000..9c3aa630c2 --- /dev/null +++ b/third_party/agg23/agg_vcgen_dash.h @@ -0,0 +1,75 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Line dash generator +// +//---------------------------------------------------------------------------- +#ifndef AGG_VCGEN_DASH_INCLUDED +#define AGG_VCGEN_DASH_INCLUDED +#include "agg_basics.h" +#include "agg_vertex_sequence.h" +namespace agg +{ +class vcgen_dash +{ + enum max_dashes_e { + max_dashes = 32 + }; + enum status_e { + initial, + ready, + polyline, + stop + }; +public: + typedef vertex_sequence vertex_storage; + vcgen_dash(); + void remove_all_dashes(); + void add_dash(FX_FLOAT dash_len, FX_FLOAT gap_len); + void dash_start(FX_FLOAT ds); + void shorten(FX_FLOAT s) + { + m_shorten = s; + } + double shorten() const + { + return m_shorten; + } + void remove_all(); + void add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd); + void rewind(unsigned path_id); + unsigned vertex(FX_FLOAT* x, FX_FLOAT* y); +private: + vcgen_dash(const vcgen_dash&); + const vcgen_dash& operator = (const vcgen_dash&); + void calc_dash_start(FX_FLOAT ds); + FX_FLOAT m_dashes[max_dashes]; + FX_FLOAT m_total_dash_len; + unsigned m_num_dashes; + FX_FLOAT m_dash_start; + FX_FLOAT m_shorten; + FX_FLOAT m_curr_dash_start; + unsigned m_curr_dash; + FX_FLOAT m_curr_rest; + const vertex_dist* m_v1; + const vertex_dist* m_v2; + vertex_storage m_src_vertices; + unsigned m_closed; + status_e m_status; + unsigned m_src_vertex; +}; +} +#endif diff --git a/third_party/agg23/agg_vcgen_stroke.cpp b/third_party/agg23/agg_vcgen_stroke.cpp new file mode 100644 index 0000000000..9b8cb66fd9 --- /dev/null +++ b/third_party/agg23/agg_vcgen_stroke.cpp @@ -0,0 +1,214 @@ + +//---------------------------------------------------------------------------- +// XYQ: 2006-01-22 Copied from AGG project. +// TODO: This file uses intensive floating point operations, so it's NOT suitable +// for platforms like Symbian OS. We need to change to FIX format. +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Stroke generator +// +//---------------------------------------------------------------------------- +#include "../../core/include/fxcrt/fx_basic.h" +#include "agg_vcgen_stroke.h" +namespace agg +{ + +vcgen_stroke::vcgen_stroke() : + m_src_vertices(), + m_out_vertices(), + m_width(0.5f), + m_miter_limit(4 * 1.0f), + m_inner_miter_limit(1.0f + 1.0f / 100), + m_approx_scale(1.0f), + m_line_cap(butt_cap), + m_line_join(miter_join), + m_inner_join(inner_miter), + m_closed(0), + m_status(initial), + m_src_vertex(0), + m_out_vertex(0) +{ +} +void vcgen_stroke::remove_all() +{ + m_src_vertices.remove_all(); + m_closed = 0; + m_status = initial; +} +void vcgen_stroke::add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd) +{ + m_status = initial; + if(is_move_to(cmd)) { + m_src_vertices.modify_last(vertex_dist_cmd(x, y, cmd)); + } else { + if(is_vertex(cmd)) { + m_src_vertices.add(vertex_dist_cmd(x, y, cmd)); + } else { + m_closed = get_close_flag(cmd); + } + } +} +static inline void calc_butt_cap(FX_FLOAT* cap, + const vertex_dist& v0, + const vertex_dist& v1, + FX_FLOAT len, + FX_FLOAT width) +{ + FX_FLOAT dx = FXSYS_MulDiv(v1.y - v0.y, width, len); + FX_FLOAT dy = FXSYS_MulDiv(v1.x - v0.x, width, len); + cap[0] = v0.x - dx; + cap[1] = v0.y + dy; + cap[2] = v0.x + dx; + cap[3] = v0.y - dy; +} +void vcgen_stroke::rewind(unsigned) +{ + if(m_status == initial) { + m_src_vertices.close(m_closed != 0); + if(m_src_vertices.size() < 3) { + m_closed = 0; + } + } + m_status = ready; + m_src_vertex = 0; + m_out_vertex = 0; +} +unsigned vcgen_stroke::vertex(FX_FLOAT* x, FX_FLOAT* y) +{ + unsigned cmd = path_cmd_line_to; + line_join_e curj; + while(!is_stop(cmd)) { + switch(m_status) { + case initial: + rewind(0); + case ready: + if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) { + cmd = path_cmd_stop; + break; + } + m_status = m_closed ? outline1 : cap1; + cmd = path_cmd_move_to; + m_src_vertex = 0; + m_out_vertex = 0; + 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_src_vertex = 1; + m_prev_status = outline1; + m_status = out_vertices; + m_out_vertex = 0; + 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_prev_status = outline2; + m_status = out_vertices; + m_out_vertex = 0; + break; + case outline1: + if(m_closed) { + if(m_src_vertex >= m_src_vertices.size()) { + m_prev_status = close_first; + m_status = end_poly1; + break; + } + } else { + if(m_src_vertex >= m_src_vertices.size() - 1) { + m_status = cap2; + break; + } + } + curj = m_src_vertices[m_src_vertex].cmd & path_flags_jr ? miter_join_round : m_line_join; + 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, + curj, + m_inner_join, + m_miter_limit, + m_inner_miter_limit, + m_approx_scale); + ++m_src_vertex; + m_prev_status = m_status; + m_status = out_vertices; + m_out_vertex = 0; + break; + case close_first: + m_status = outline2; + cmd = path_cmd_move_to; + case outline2: + if(m_src_vertex <= unsigned(m_closed == 0)) { + m_status = end_poly2; + m_prev_status = stop; + break; + } + --m_src_vertex; + curj = m_src_vertices[m_src_vertex].cmd & path_flags_jr ? miter_join_round : m_line_join; + 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, + curj, + m_inner_join, + m_miter_limit, + m_inner_miter_limit, + m_approx_scale); + m_prev_status = m_status; + m_status = out_vertices; + m_out_vertex = 0; + break; + case out_vertices: + if(m_out_vertex >= m_out_vertices.size()) { + m_status = m_prev_status; + } else { + const point_type& c = m_out_vertices[m_out_vertex++]; + *x = c.x; + *y = c.y; + return cmd; + } + break; + case end_poly1: + m_status = m_prev_status; + return path_cmd_end_poly | path_flags_close | path_flags_ccw; + case end_poly2: + m_status = m_prev_status; + return path_cmd_end_poly | path_flags_close | path_flags_cw; + case stop: + cmd = path_cmd_stop; + break; + } + } + return cmd; +} +} diff --git a/third_party/agg23/agg_vcgen_stroke.h b/third_party/agg23/agg_vcgen_stroke.h new file mode 100644 index 0000000000..84fadd6ed8 --- /dev/null +++ b/third_party/agg23/agg_vcgen_stroke.h @@ -0,0 +1,120 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_VCGEN_STROKE_INCLUDED +#define AGG_VCGEN_STROKE_INCLUDED +#include "agg_math_stroke.h" +namespace agg +{ +class vcgen_stroke +{ + enum status_e { + initial, + ready, + cap1, + cap2, + outline1, + close_first, + outline2, + out_vertices, + end_poly1, + end_poly2, + stop + }; +public: + typedef vertex_sequence vertex_storage; + typedef pod_deque 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_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(FX_FLOAT w) + { + m_width = w / 2; + } + void miter_limit(FX_FLOAT ml) + { + m_miter_limit = ml; + } + void miter_limit_theta(FX_FLOAT t); + void inner_miter_limit(FX_FLOAT ml) + { + m_inner_miter_limit = ml; + } + void approximation_scale(FX_FLOAT as) + { + m_approx_scale = as; + } + FX_FLOAT width() const + { + return m_width * 2; + } + FX_FLOAT miter_limit() const + { + return m_miter_limit; + } + FX_FLOAT inner_miter_limit() const + { + return m_inner_miter_limit; + } + FX_FLOAT approximation_scale() const + { + return m_approx_scale; + } + void remove_all(); + void add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd); + void rewind(unsigned path_id); + unsigned vertex(FX_FLOAT* x, FX_FLOAT* y); +private: + vcgen_stroke(const vcgen_stroke&); + const vcgen_stroke& operator = (const vcgen_stroke&); + vertex_storage m_src_vertices; + coord_storage m_out_vertices; + FX_FLOAT m_width; + FX_FLOAT m_miter_limit; + FX_FLOAT m_inner_miter_limit; + FX_FLOAT m_approx_scale; + line_cap_e m_line_cap; + line_join_e m_line_join; + inner_join_e m_inner_join; + unsigned m_closed; + status_e m_status; + status_e m_prev_status; + unsigned m_src_vertex; + unsigned m_out_vertex; +}; +} +#endif diff --git a/third_party/agg23/agg_vertex_sequence.h b/third_party/agg23/agg_vertex_sequence.h new file mode 100644 index 0000000000..6600bf2085 --- /dev/null +++ b/third_party/agg23/agg_vertex_sequence.h @@ -0,0 +1,100 @@ + +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// vertex_sequence container and vertex_dist struct +// +//---------------------------------------------------------------------------- +#ifndef AGG_VERTEX_SEQUENCE_INCLUDED +#define AGG_VERTEX_SEQUENCE_INCLUDED +#include "agg_basics.h" +#include "agg_array.h" +#include "agg_math.h" +namespace agg +{ +template +class vertex_sequence : public pod_deque +{ +public: + typedef pod_deque base_type; + void add(const T& val); + void modify_last(const T& val); + void close(bool remove_flag); +}; +template +void vertex_sequence::add(const T& val) +{ + if(base_type::size() > 1) { + if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) { + base_type::remove_last(); + } + } + base_type::add(val); +} +template +void vertex_sequence::modify_last(const T& val) +{ + base_type::remove_last(); + add(val); +} +template +void vertex_sequence::close(bool closed) +{ + while(base_type::size() > 1) { + if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) { + break; + } + T t = (*this)[base_type::size() - 1]; + base_type::remove_last(); + modify_last(t); + } + if(closed) { + while(base_type::size() > 1) { + if((*this)[base_type::size() - 1]((*this)[0])) { + break; + } + base_type::remove_last(); + } + } +} +const FX_FLOAT vertex_dist_epsilon = 1e-14f; +struct vertex_dist { + FX_FLOAT x; + FX_FLOAT y; + FX_FLOAT dist; + vertex_dist() {} + vertex_dist(FX_FLOAT x_, FX_FLOAT y_) : + x(x_), + y(y_), + dist(0) + { + } + bool operator () (const vertex_dist& val) + { + bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon; + return ret; + } +}; +struct vertex_dist_cmd : public vertex_dist { + unsigned cmd; + vertex_dist_cmd() {} + vertex_dist_cmd(FX_FLOAT x_, FX_FLOAT y_, unsigned cmd_) : + vertex_dist(x_, y_), + cmd(cmd_) + { + } +}; +} +#endif diff --git a/third_party/third_party.gyp b/third_party/third_party.gyp index b6978658dd..8538001e7f 100644 --- a/third_party/third_party.gyp +++ b/third_party/third_party.gyp @@ -20,6 +20,33 @@ 'bigint/BigUnsignedInABase.cc', ], }, + { + 'target_name': 'fx_agg', + 'type': 'static_library', + 'sources': [ + 'agg23/agg_basics.h', + 'agg23/agg_clip_liang_barsky.h', + 'agg23/agg_conv_dash.h', + 'agg23/agg_conv_stroke.h', + 'agg23/agg_curves.cpp', + 'agg23/agg_curves.h', + 'agg23/agg_path_storage.cpp', + 'agg23/agg_path_storage.h', + 'agg23/agg_rasterizer_scanline_aa.cpp', + 'agg23/agg_rasterizer_scanline_aa.h', + 'agg23/agg_renderer_scanline.h', + 'agg23/agg_rendering_buffer.h', + 'agg23/agg_scanline_u.h', + 'agg23/agg_vcgen_dash.cpp', + 'agg23/agg_vcgen_stroke.cpp', + ], + 'conditions': [ + ['os_posix==1', { + # library contains several enum vs non-enum conditionals. + 'cflags': [ '-Wno-extra', ], + }], + ], + }, { 'target_name': 'freetype', 'type': 'static_library', -- cgit v1.2.3