diff --git a/haiku-apps/clockwerk/patches/clockwerk-1.0~git.patchset b/haiku-apps/clockwerk/patches/clockwerk-1.0~git.patchset deleted file mode 100644 index f9bce01c9..000000000 --- a/haiku-apps/clockwerk/patches/clockwerk-1.0~git.patchset +++ /dev/null @@ -1,10427 +0,0 @@ -From c0ae410f5f2b381e5d1a8bd873270a242b5017f5 Mon Sep 17 00:00:00 2001 -From: Jerome Duval -Date: Mon, 17 Sep 2018 20:33:30 +0200 -Subject: update agg to version 2.4 from Haiku tree. - - -diff --git a/src/editor/tools/transform/DragStates.cpp b/src/editor/tools/transform/DragStates.cpp -index 165aba8..9ae6b39 100644 ---- a/src/editor/tools/transform/DragStates.cpp -+++ b/src/editor/tools/transform/DragStates.cpp -@@ -48,6 +48,25 @@ snap_scale(double scale) - return scale * sign; - } - -+ -+// from 2.x agg_trans_affine.cpp -+static inline void -+rect_to_rect(agg::trans_affine& a, double x1, double y1, -+ double x2, double y2, double x3, double y3, -+ double x4, double y4) { -+ double src[6]; -+ src[0] = x1; src[1] = y1; -+ src[2] = x2; src[3] = y1; -+ src[4] = x2; src[5] = y2; -+ -+ double dst[6]; -+ dst[0] = x3; dst[1] = y3; -+ dst[2] = x4; dst[3] = y3; -+ dst[4] = x4; dst[5] = y4; -+ -+ a.parl_to_parl(src, dst); -+} -+ - //------------------------------------------------------------------ - // DragState - -@@ -200,7 +219,7 @@ DragCornerState::DragTo(BPoint current, uint32 modifiers) - // distortion of the box with the opposite - // corner of the one being dragged staying fixed - AffineTransform s; -- s.rect_to_rect(oldBox.left, oldBox.top, oldBox.right, oldBox.bottom, -+ rect_to_rect(s, oldBox.left, oldBox.top, oldBox.right, oldBox.bottom, - newBox.left, newBox.top, newBox.right, newBox.bottom); - - // construct a transformation that -@@ -473,7 +492,7 @@ DragSideState::DragTo(BPoint current, uint32 modifiers) - // distortion of the box with the opposite - // corner of the one being dragged staying fixed - AffineTransform s; -- s.rect_to_rect(oldBox.left, oldBox.top, oldBox.right, oldBox.bottom, -+ rect_to_rect(s, oldBox.left, oldBox.top, oldBox.right, oldBox.bottom, - newBox.left, newBox.top, newBox.right, newBox.bottom); - - // construct a transformation that -diff --git a/src/shared/generic/regex.cpp b/src/shared/generic/regex.cpp -index c6405b8..766f208 100644 ---- a/src/shared/generic/regex.cpp -+++ b/src/shared/generic/regex.cpp -@@ -2874,7 +2874,7 @@ re_set_registers (struct re_pattern_buffer * bufp, struct re_registers * regs, - { - bufp->regs_allocated = REGS_UNALLOCATED; - regs->num_regs = 0; -- regs->start = regs->end = (regoff_t) 0; -+ regs->start = regs->end = NULL; - } - } - -diff --git a/src/shared/painter/FontCacheEntry.cpp b/src/shared/painter/FontCacheEntry.cpp -index 7c36f61..3fb475f 100644 ---- a/src/shared/painter/FontCacheEntry.cpp -+++ b/src/shared/painter/FontCacheEntry.cpp -@@ -82,7 +82,7 @@ class FontCacheEntry::GlyphCachePool { - } - - private: -- agg::pod_allocator fAllocator; -+ agg::block_allocator fAllocator; - GlyphCache** fGlyphs[256]; - }; - -diff --git a/src/third_party/agg/include/agg_alpha_mask_u8.h b/src/third_party/agg/include/agg_alpha_mask_u8.h -index b325c54..50081a8 100644 ---- a/src/third_party/agg/include/agg_alpha_mask_u8.h -+++ b/src/third_party/agg/include/agg_alpha_mask_u8.h -@@ -70,7 +70,7 @@ namespace agg - { - if(x >= 0 && y >= 0 && - x < (int)m_rbuf->width() && -- y <= (int)m_rbuf->height()) -+ y < (int)m_rbuf->height()) - { - return (cover_type)m_mask_function.calculate( - m_rbuf->row_ptr(y) + x * Step + Offset); -@@ -83,7 +83,7 @@ namespace agg - { - if(x >= 0 && y >= 0 && - x < (int)m_rbuf->width() && -- y <= (int)m_rbuf->height()) -+ y < (int)m_rbuf->height()) - { - return (cover_type)((cover_full + val * - m_mask_function.calculate( -diff --git a/src/third_party/agg/include/agg_array.h b/src/third_party/agg/include/agg_array.h -index 57f8ae6..8d56683 100644 ---- a/src/third_party/agg/include/agg_array.h -+++ b/src/third_party/agg/include/agg_array.h -@@ -109,20 +109,27 @@ namespace agg - typedef T value_type; - typedef pod_array self_type; - -- ~pod_array() { delete [] m_array; } -+ ~pod_array() { pod_allocator::deallocate(m_array, m_size); } - pod_array() : m_array(0), m_size(0) {} -- pod_array(unsigned size) : m_array(new T[size]), m_size(size) {} -+ -+ pod_array(unsigned size) : -+ m_array(pod_allocator::allocate(size)), -+ m_size(size) -+ {} -+ - pod_array(const self_type& v) : -- m_array(new T[v.m_size]), m_size(v.m_size) -+ m_array(pod_allocator::allocate(v.m_size)), -+ m_size(v.m_size) - { - memcpy(m_array, v.m_array, sizeof(T) * m_size); - } -+ - void resize(unsigned size) - { - if(size != m_size) - { -- delete [] m_array; -- m_array = new T[m_size = size]; -+ pod_allocator::deallocate(m_array, m_size); -+ m_array = pod_allocator::allocate(m_size = size); - } - } - const self_type& operator = (const self_type& v) -@@ -157,7 +164,7 @@ namespace agg - public: - typedef T value_type; - -- ~pod_vector() { delete [] m_array; } -+ ~pod_vector() { pod_allocator::deallocate(m_array, m_capacity); } - pod_vector() : m_size(0), m_capacity(0), m_array(0) {} - pod_vector(unsigned cap, unsigned extra_tail=0); - -@@ -215,9 +222,9 @@ namespace agg - m_size = 0; - if(cap > m_capacity) - { -- delete [] m_array; -+ pod_allocator::deallocate(m_array, m_capacity); - m_capacity = cap + extra_tail; -- m_array = m_capacity ? new T [m_capacity] : 0; -+ m_array = m_capacity ? pod_allocator::allocate(m_capacity) : 0; - } - } - -@@ -238,9 +245,9 @@ namespace agg - { - if(new_size > m_capacity) - { -- T* data = new T[new_size]; -+ T* data = pod_allocator::allocate(new_size); - memcpy(data, m_array, m_size * sizeof(T)); -- delete [] m_array; -+ pod_allocator::deallocate(m_array, m_capacity); - m_array = data; - } - } -@@ -252,13 +259,15 @@ namespace agg - - //------------------------------------------------------------------------ - template pod_vector::pod_vector(unsigned cap, unsigned extra_tail) : -- m_size(0), m_capacity(cap + extra_tail), m_array(new T[m_capacity]) {} -+ m_size(0), -+ m_capacity(cap + extra_tail), -+ m_array(pod_allocator::allocate(m_capacity)) {} - - //------------------------------------------------------------------------ - template pod_vector::pod_vector(const pod_vector& v) : - m_size(v.m_size), - m_capacity(v.m_capacity), -- m_array(v.m_capacity ? new T [v.m_capacity] : 0) -+ m_array(v.m_capacity ? pod_allocator::allocate(v.m_capacity) : 0) - { - memcpy(m_array, v.m_array, sizeof(T) * v.m_size); - } -@@ -509,11 +518,11 @@ namespace agg - T** blk = m_blocks + m_num_blocks - 1; - while(m_num_blocks--) - { -- delete [] *blk; -+ pod_allocator::deallocate(*blk, block_size); - --blk; - } -- delete [] m_blocks; - } -+ pod_allocator::deallocate(m_blocks, m_max_blocks); - } - - -@@ -526,7 +535,13 @@ namespace agg - unsigned nb = (size + block_mask) >> block_shift; - while(m_num_blocks > nb) - { -- delete [] m_blocks[--m_num_blocks]; -+ pod_allocator::deallocate(m_blocks[--m_num_blocks], block_size); -+ } -+ if(m_num_blocks == 0) -+ { -+ pod_allocator::deallocate(m_blocks, m_max_blocks); -+ m_blocks = 0; -+ m_max_blocks = 0; - } - m_size = size; - } -@@ -562,13 +577,15 @@ namespace agg - m_size(v.m_size), - m_num_blocks(v.m_num_blocks), - m_max_blocks(v.m_max_blocks), -- m_blocks(v.m_max_blocks ? new T* [v.m_max_blocks] : 0), -+ m_blocks(v.m_max_blocks ? -+ pod_allocator::allocate(v.m_max_blocks) : -+ 0), - m_block_ptr_inc(v.m_block_ptr_inc) - { - unsigned i; - for(i = 0; i < v.m_num_blocks; ++i) - { -- m_blocks[i] = new T [block_size]; -+ m_blocks[i] = pod_allocator::allocate(block_size); - memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); - } - } -@@ -599,7 +616,7 @@ namespace agg - { - if(nb >= m_max_blocks) - { -- T** new_blocks = new T* [m_max_blocks + m_block_ptr_inc]; -+ T** new_blocks = pod_allocator::allocate(m_max_blocks + m_block_ptr_inc); - - if(m_blocks) - { -@@ -607,12 +624,12 @@ namespace agg - m_blocks, - m_num_blocks * sizeof(T*)); - -- delete [] m_blocks; -+ pod_allocator::deallocate(m_blocks, m_max_blocks); - } - m_blocks = new_blocks; - m_max_blocks += m_block_ptr_inc; - } -- m_blocks[nb] = new T [block_size]; -+ m_blocks[nb] = pod_allocator::allocate(block_size); - m_num_blocks++; - } - -@@ -753,7 +770,7 @@ namespace agg - } - - -- //-----------------------------------------------------------pod_allocator -+ //---------------------------------------------------------block_allocator - // Allocator for arbitrary POD data. Most usable in different cache - // systems for efficient memory allocations. - // Memory is allocated with blocks of fixed size ("block_size" in -@@ -761,20 +778,26 @@ namespace agg - // creates a new block of the required size. However, the most efficient - // use is when the average reqired size is much less than the block size. - //------------------------------------------------------------------------ -- class pod_allocator -+ class block_allocator - { -+ struct block_type -+ { -+ int8u* data; -+ unsigned size; -+ }; -+ - public: - void remove_all() - { - if(m_num_blocks) - { -- int8u** blk = m_blocks + m_num_blocks - 1; -+ block_type* blk = m_blocks + m_num_blocks - 1; - while(m_num_blocks--) - { -- delete [] *blk; -+ pod_allocator::deallocate(blk->data, blk->size); - --blk; - } -- delete [] m_blocks; -+ pod_allocator::deallocate(m_blocks, m_max_blocks); - } - m_num_blocks = 0; - m_max_blocks = 0; -@@ -783,12 +806,12 @@ namespace agg - m_rest = 0; - } - -- ~pod_allocator() -+ ~block_allocator() - { - remove_all(); - } - -- pod_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) : -+ block_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) : - m_block_size(block_size), - m_block_ptr_inc(block_ptr_inc), - m_num_blocks(0), -@@ -808,7 +831,9 @@ namespace agg - int8u* ptr = m_buf_ptr; - if(alignment > 1) - { -- unsigned align = (alignment - unsigned((size_t)ptr) % alignment) % alignment; -+ unsigned align = -+ (alignment - unsigned((size_t)ptr) % alignment) % alignment; -+ - size += align; - ptr += align; - if(size <= m_rest) -@@ -835,31 +860,36 @@ namespace agg - if(size < m_block_size) size = m_block_size; - if(m_num_blocks >= m_max_blocks) - { -- int8u** new_blocks = new int8u* [m_max_blocks + m_block_ptr_inc]; -+ block_type* new_blocks = -+ pod_allocator::allocate(m_max_blocks + m_block_ptr_inc); - - if(m_blocks) - { - memcpy(new_blocks, - m_blocks, -- m_num_blocks * sizeof(int8u*)); -- -- delete [] m_blocks; -+ m_num_blocks * sizeof(block_type)); -+ pod_allocator::deallocate(m_blocks, m_max_blocks); - } - m_blocks = new_blocks; - m_max_blocks += m_block_ptr_inc; - } -- m_blocks[m_num_blocks] = m_buf_ptr = new int8u [size]; -+ -+ m_blocks[m_num_blocks].size = size; -+ m_blocks[m_num_blocks].data = -+ m_buf_ptr = -+ pod_allocator::allocate(size); -+ - m_num_blocks++; - m_rest = size; - } - -- unsigned m_block_size; -- unsigned m_block_ptr_inc; -- unsigned m_num_blocks; -- unsigned m_max_blocks; -- int8u** m_blocks; -- int8u* m_buf_ptr; -- unsigned m_rest; -+ unsigned m_block_size; -+ unsigned m_block_ptr_inc; -+ unsigned m_num_blocks; -+ unsigned m_max_blocks; -+ block_type* m_blocks; -+ int8u* m_buf_ptr; -+ unsigned m_rest; - }; - - -@@ -1014,6 +1044,16 @@ namespace agg - return j; - } - -+ //--------------------------------------------------------invert_container -+ template void invert_container(Array& arr) -+ { -+ int i = 0; -+ int j = arr.size() - 1; -+ while(i < j) -+ { -+ swap_elements(arr[i++], arr[j--]); -+ } -+ } - - //------------------------------------------------------binary_search_pos - template -@@ -1033,16 +1073,47 @@ namespace agg - if(less(val, arr[mid])) end = mid; - else beg = mid; - } --/* -- if(beg <= 0 && -- less(val, arr[0])) return 0; - -- if(end >= arr.size() - 1 && -- less(arr[end], val)) ++end; --*/ -+ //if(beg <= 0 && less(val, arr[0])) return 0; -+ //if(end >= arr.size() - 1 && less(arr[end], val)) ++end; -+ - return end; - } - -+ //----------------------------------------------------------range_adaptor -+ template class range_adaptor -+ { -+ public: -+ typedef typename Array::value_type value_type; -+ -+ range_adaptor(Array& array, unsigned start, unsigned size) : -+ m_array(array), m_start(start), m_size(size) -+ {} -+ -+ unsigned size() const { return m_size; } -+ const value_type& operator [] (unsigned i) const { return m_array[m_start + i]; } -+ value_type& operator [] (unsigned i) { return m_array[m_start + i]; } -+ const value_type& at(unsigned i) const { return m_array[m_start + i]; } -+ value_type& at(unsigned i) { return m_array[m_start + i]; } -+ value_type value_at(unsigned i) const { return m_array[m_start + i]; } -+ -+ private: -+ Array& m_array; -+ unsigned m_start; -+ unsigned m_size; -+ }; -+ -+ //---------------------------------------------------------------int_less -+ inline bool int_less(int a, int b) { return a < b; } -+ -+ //------------------------------------------------------------int_greater -+ inline bool int_greater(int a, int b) { return a > b; } -+ -+ //----------------------------------------------------------unsigned_less -+ inline bool unsigned_less(unsigned a, unsigned b) { return a < b; } -+ -+ //-------------------------------------------------------unsigned_greater -+ inline bool unsigned_greater(unsigned a, unsigned b) { return a > b; } - } - - #endif -diff --git a/src/third_party/agg/include/agg_basics.h b/src/third_party/agg/include/agg_basics.h -index cf3cc5f..3097130 100644 ---- a/src/third_party/agg/include/agg_basics.h -+++ b/src/third_party/agg/include/agg_basics.h -@@ -19,6 +19,43 @@ - #include - #include "agg_config.h" - -+//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR -+#ifdef AGG_CUSTOM_ALLOCATOR -+#include "agg_allocator.h" -+#else -+namespace agg -+{ -+ // The policy of all AGG containers and memory allocation strategy -+ // in general is that no allocated data requires explicit construction. -+ // It means that the allocator can be really simple; you can even -+ // replace new/delete to malloc/free. The constructors and destructors -+ // won't be called in this case, however everything will remain working. -+ // The second argument of deallocate() is the size of the allocated -+ // block. You can use this information if you wish. -+ //------------------------------------------------------------pod_allocator -+ template struct pod_allocator -+ { -+ static T* allocate(unsigned num) { return new T [num]; } -+ static void deallocate(T* ptr, unsigned) { delete [] ptr; } -+ }; -+ -+ // Single object allocator. It's also can be replaced with your custom -+ // allocator. The difference is that it can only allocate a single -+ // object and the constructor and destructor must be called. -+ // In AGG there is no need to allocate an array of objects with -+ // calling their constructors (only single ones). So that, if you -+ // replace these new/delete to malloc/free make sure that the in-place -+ // new is called and take care of calling the destructor too. -+ //------------------------------------------------------------obj_allocator -+ template struct obj_allocator -+ { -+ static T* allocate() { return new T; } -+ static void deallocate(T* ptr) { delete ptr; } -+ }; -+} -+#endif -+ -+ - //-------------------------------------------------------- Default basic types - // - // If the compiler has different capacity of the basic types you can redefine -@@ -93,21 +130,31 @@ namespace agg - #pragma warning(disable : 4035) //Disable warning "no return value" - AGG_INLINE int iround(double v) //-------iround - { -+ int t; - __asm fld qword ptr [v] -- __asm fistp dword ptr [ebp-8] -- __asm mov eax, dword ptr [ebp-8] -+ __asm fistp dword ptr [t] -+ __asm mov eax, dword ptr [t] - } - AGG_INLINE unsigned uround(double v) //-------uround - { -+ unsigned t; - __asm fld qword ptr [v] -- __asm fistp dword ptr [ebp-8] -- __asm mov eax, dword ptr [ebp-8] -+ __asm fistp dword ptr [t] -+ __asm mov eax, dword ptr [t] - } - #pragma warning(pop) -+ AGG_INLINE int ifloor(double v) -+ { -+ return int(floor(v)); -+ } - AGG_INLINE unsigned ufloor(double v) //-------ufloor - { - return unsigned(floor(v)); - } -+ AGG_INLINE int iceil(double v) -+ { -+ return int(ceil(v)); -+ } - AGG_INLINE unsigned uceil(double v) //--------uceil - { - return unsigned(ceil(v)); -@@ -121,10 +168,18 @@ namespace agg - { - return unsigned(v); - } -+ AGG_INLINE int ifloor(double v) -+ { -+ return int(floor(v)); -+ } - AGG_INLINE unsigned ufloor(double v) - { - return unsigned(floor(v)); - } -+ AGG_INLINE int iceil(double v) -+ { -+ return int(ceil(v)); -+ } - AGG_INLINE unsigned uceil(double v) - { - return unsigned(ceil(v)); -@@ -138,10 +193,19 @@ namespace agg - { - return unsigned(v + 0.5); - } -+ AGG_INLINE int ifloor(double v) -+ { -+ int i = int(v); -+ return i - (i > v); -+ } - AGG_INLINE unsigned ufloor(double v) - { - return unsigned(v); - } -+ AGG_INLINE int iceil(double v) -+ { -+ return int(ceil(v)); -+ } - AGG_INLINE unsigned uceil(double v) - { - return unsigned(ceil(v)); -@@ -164,7 +228,7 @@ namespace agg - { - AGG_INLINE static unsigned mul(unsigned a, unsigned b) - { -- register unsigned q = a * b + (1 << (Shift-1)); -+ unsigned q = a * b + (1 << (Shift-1)); - return (q + (q >> Shift)) >> Shift; - } - }; -@@ -190,7 +254,14 @@ namespace agg - { - poly_subpixel_shift = 8, //----poly_subpixel_shift - poly_subpixel_scale = 1< struct rect_base - { -+ typedef T value_type; - typedef rect_base self_type; -- T x1; -- T y1; -- T x2; -- T y2; -+ T x1, y1, x2, y2; - - rect_base() {} - rect_base(T x1_, T y1_, T x2_, T y2_) : - x1(x1_), y1(y1_), x2(x2_), y2(y2_) {} - -+ void init(T x1_, T y1_, T x2_, T y2_) -+ { -+ x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_; -+ } -+ - const self_type& normalize() - { - T t; -@@ -242,6 +316,17 @@ namespace agg - { - return x1 <= x2 && y1 <= y2; - } -+ -+ bool hit_test(T x, T y) const -+ { -+ return (x >= x1 && x <= x2 && y >= y1 && y <= y2); -+ } -+ -+ bool overlaps(const self_type& r) const -+ { -+ return !(r.x1 > x2 || r.x2 < x1 -+ || r.y1 > y2 || r.y2 < y1); -+ } - }; - - //-----------------------------------------------------intersect_rectangles -@@ -444,6 +529,30 @@ namespace agg - typedef vertex_base vertex_f; //-----vertex_f - typedef vertex_base vertex_d; //-----vertex_d - -+ //----------------------------------------------------------------row_info -+ template struct row_info -+ { -+ int x1, x2; -+ T* ptr; -+ row_info() {} -+ row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {} -+ }; -+ -+ //----------------------------------------------------------const_row_info -+ template struct const_row_info -+ { -+ int x1, x2; -+ const T* ptr; -+ const_row_info() {} -+ const_row_info(int x1_, int x2_, const T* ptr_) : -+ x1(x1_), x2(x2_), ptr(ptr_) {} -+ }; -+ -+ //------------------------------------------------------------is_equal_eps -+ template inline bool is_equal_eps(T v1, T v2, T epsilon) -+ { -+ return fabs(v1 - v2) <= double(epsilon); -+ } - } - - -diff --git a/src/third_party/agg/include/agg_blur.h b/src/third_party/agg/include/agg_blur.h -new file mode 100644 -index 0000000..0860f52 ---- /dev/null -+++ b/src/third_party/agg/include/agg_blur.h -@@ -0,0 +1,1294 @@ -+//---------------------------------------------------------------------------- -+// Anti-Grain Geometry - Version 2.4 -+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -+// -+// Permission to copy, use, modify, sell and distribute this software -+// is granted provided this copyright notice appears in all copies. -+// This software is provided "as is" without express or implied -+// warranty, and with no claim as to its suitability for any purpose. -+// -+//---------------------------------------------------------------------------- -+// Contact: mcseem@antigrain.com -+// mcseemagg@yahoo.com -+// http://www.antigrain.com -+//---------------------------------------------------------------------------- -+// -+// The Stack Blur Algorithm was invented by Mario Klingemann, -+// mario@quasimondo.com and described here: -+// http://incubator.quasimondo.com/processing/fast_blur_deluxe.php -+// (search phrase "Stackblur: Fast But Goodlooking"). -+// The major improvement is that there's no more division table -+// that was very expensive to create for large blur radii. Insted, -+// for 8-bit per channel and radius not exceeding 254 the division is -+// replaced by multiplication and shift. -+// -+//---------------------------------------------------------------------------- -+ -+#ifndef AGG_BLUR_INCLUDED -+#define AGG_BLUR_INCLUDED -+ -+#include "agg_array.h" -+#include "agg_pixfmt_transposer.h" -+ -+namespace agg -+{ -+ -+ template struct stack_blur_tables -+ { -+ static int16u const g_stack_blur8_mul[255]; -+ static int8u const g_stack_blur8_shr[255]; -+ }; -+ -+ //------------------------------------------------------------------------ -+ template -+ int16u const stack_blur_tables::g_stack_blur8_mul[255] = -+ { -+ 512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512, -+ 454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512, -+ 482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456, -+ 437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512, -+ 497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328, -+ 320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456, -+ 446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335, -+ 329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512, -+ 505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405, -+ 399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328, -+ 324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271, -+ 268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456, -+ 451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388, -+ 385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335, -+ 332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292, -+ 289,287,285,282,280,278,275,273,271,269,267,265,263,261,259 -+ }; -+ -+ //------------------------------------------------------------------------ -+ template -+ int8u const stack_blur_tables::g_stack_blur8_shr[255] = -+ { -+ 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, -+ 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, -+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, -+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, -+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, -+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, -+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, -+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -+ 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 -+ }; -+ -+ -+ -+ //==============================================================stack_blur -+ template class stack_blur -+ { -+ public: -+ typedef ColorT color_type; -+ typedef CalculatorT calculator_type; -+ -+ //-------------------------------------------------------------------- -+ template void blur_x(Img& img, unsigned radius) -+ { -+ if(radius < 1) return; -+ -+ unsigned x, y, xp, i; -+ unsigned stack_ptr; -+ unsigned stack_start; -+ -+ color_type pix; -+ color_type* stack_pix; -+ calculator_type sum; -+ calculator_type sum_in; -+ calculator_type sum_out; -+ -+ unsigned w = img.width(); -+ unsigned h = img.height(); -+ unsigned wm = w - 1; -+ unsigned div = radius * 2 + 1; -+ -+ unsigned div_sum = (radius + 1) * (radius + 1); -+ unsigned mul_sum = 0; -+ unsigned shr_sum = 0; -+ unsigned max_val = color_type::base_mask; -+ -+ if(max_val <= 255 && radius < 255) -+ { -+ mul_sum = stack_blur_tables::g_stack_blur8_mul[radius]; -+ shr_sum = stack_blur_tables::g_stack_blur8_shr[radius]; -+ } -+ -+ m_buf.allocate(w, 128); -+ m_stack.allocate(div, 32); -+ -+ for(y = 0; y < h; y++) -+ { -+ sum.clear(); -+ sum_in.clear(); -+ sum_out.clear(); -+ -+ pix = img.pixel(0, y); -+ for(i = 0; i <= radius; i++) -+ { -+ m_stack[i] = pix; -+ sum.add(pix, i + 1); -+ sum_out.add(pix); -+ } -+ for(i = 1; i <= radius; i++) -+ { -+ pix = img.pixel((i > wm) ? wm : i, y); -+ m_stack[i + radius] = pix; -+ sum.add(pix, radius + 1 - i); -+ sum_in.add(pix); -+ } -+ -+ stack_ptr = radius; -+ for(x = 0; x < w; x++) -+ { -+ if(mul_sum) sum.calc_pix(m_buf[x], mul_sum, shr_sum); -+ else sum.calc_pix(m_buf[x], div_sum); -+ -+ sum.sub(sum_out); -+ -+ stack_start = stack_ptr + div - radius; -+ if(stack_start >= div) stack_start -= div; -+ stack_pix = &m_stack[stack_start]; -+ -+ sum_out.sub(*stack_pix); -+ -+ xp = x + radius + 1; -+ if(xp > wm) xp = wm; -+ pix = img.pixel(xp, y); -+ -+ *stack_pix = pix; -+ -+ sum_in.add(pix); -+ sum.add(sum_in); -+ -+ ++stack_ptr; -+ if(stack_ptr >= div) stack_ptr = 0; -+ stack_pix = &m_stack[stack_ptr]; -+ -+ sum_out.add(*stack_pix); -+ sum_in.sub(*stack_pix); -+ } -+ img.copy_color_hspan(0, y, w, &m_buf[0]); -+ } -+ } -+ -+ //-------------------------------------------------------------------- -+ template void blur_y(Img& img, unsigned radius) -+ { -+ pixfmt_transposer img2(img); -+ blur_x(img2, radius); -+ } -+ -+ //-------------------------------------------------------------------- -+ template void blur(Img& img, unsigned radius) -+ { -+ blur_x(img, radius); -+ pixfmt_transposer img2(img); -+ blur_x(img2, radius); -+ } -+ -+ private: -+ pod_vector m_buf; -+ pod_vector m_stack; -+ }; -+ -+ //====================================================stack_blur_calc_rgba -+ template struct stack_blur_calc_rgba -+ { -+ typedef T value_type; -+ value_type r,g,b,a; -+ -+ AGG_INLINE void clear() -+ { -+ r = g = b = a = 0; -+ } -+ -+ template AGG_INLINE void add(const ArgT& v) -+ { -+ r += v.r; -+ g += v.g; -+ b += v.b; -+ a += v.a; -+ } -+ -+ template AGG_INLINE void add(const ArgT& v, unsigned k) -+ { -+ r += v.r * k; -+ g += v.g * k; -+ b += v.b * k; -+ a += v.a * k; -+ } -+ -+ template AGG_INLINE void sub(const ArgT& v) -+ { -+ r -= v.r; -+ g -= v.g; -+ b -= v.b; -+ a -= v.a; -+ } -+ -+ template AGG_INLINE void calc_pix(ArgT& v, unsigned div) -+ { -+ typedef typename ArgT::value_type value_type; -+ v.r = value_type(r / div); -+ v.g = value_type(g / div); -+ v.b = value_type(b / div); -+ v.a = value_type(a / div); -+ } -+ -+ template -+ AGG_INLINE void calc_pix(ArgT& v, unsigned mul, unsigned shr) -+ { -+ typedef typename ArgT::value_type value_type; -+ v.r = value_type((r * mul) >> shr); -+ v.g = value_type((g * mul) >> shr); -+ v.b = value_type((b * mul) >> shr); -+ v.a = value_type((a * mul) >> shr); -+ } -+ }; -+ -+ -+ //=====================================================stack_blur_calc_rgb -+ template struct stack_blur_calc_rgb -+ { -+ typedef T value_type; -+ value_type r,g,b; -+ -+ AGG_INLINE void clear() -+ { -+ r = g = b = 0; -+ } -+ -+ template AGG_INLINE void add(const ArgT& v) -+ { -+ r += v.r; -+ g += v.g; -+ b += v.b; -+ } -+ -+ template AGG_INLINE void add(const ArgT& v, unsigned k) -+ { -+ r += v.r * k; -+ g += v.g * k; -+ b += v.b * k; -+ } -+ -+ template AGG_INLINE void sub(const ArgT& v) -+ { -+ r -= v.r; -+ g -= v.g; -+ b -= v.b; -+ } -+ -+ template AGG_INLINE void calc_pix(ArgT& v, unsigned div) -+ { -+ typedef typename ArgT::value_type value_type; -+ v.r = value_type(r / div); -+ v.g = value_type(g / div); -+ v.b = value_type(b / div); -+ } -+ -+ template -+ AGG_INLINE void calc_pix(ArgT& v, unsigned mul, unsigned shr) -+ { -+ typedef typename ArgT::value_type value_type; -+ v.r = value_type((r * mul) >> shr); -+ v.g = value_type((g * mul) >> shr); -+ v.b = value_type((b * mul) >> shr); -+ } -+ }; -+ -+ -+ //====================================================stack_blur_calc_gray -+ template struct stack_blur_calc_gray -+ { -+ typedef T value_type; -+ value_type v; -+ -+ AGG_INLINE void clear() -+ { -+ v = 0; -+ } -+ -+ template AGG_INLINE void add(const ArgT& a) -+ { -+ v += a.v; -+ } -+ -+ template AGG_INLINE void add(const ArgT& a, unsigned k) -+ { -+ v += a.v * k; -+ } -+ -+ template AGG_INLINE void sub(const ArgT& a) -+ { -+ v -= a.v; -+ } -+ -+ template AGG_INLINE void calc_pix(ArgT& a, unsigned div) -+ { -+ typedef typename ArgT::value_type value_type; -+ a.v = value_type(v / div); -+ } -+ -+ template -+ AGG_INLINE void calc_pix(ArgT& a, unsigned mul, unsigned shr) -+ { -+ typedef typename ArgT::value_type value_type; -+ a.v = value_type((v * mul) >> shr); -+ } -+ }; -+ -+ -+ -+ //========================================================stack_blur_gray8 -+ template -+ void stack_blur_gray8(Img& img, unsigned rx, unsigned ry) -+ { -+ unsigned x, y, xp, yp, i; -+ unsigned stack_ptr; -+ unsigned stack_start; -+ -+ const int8u* src_pix_ptr; -+ int8u* dst_pix_ptr; -+ unsigned pix; -+ unsigned stack_pix; -+ unsigned sum; -+ unsigned sum_in; -+ unsigned sum_out; -+ -+ unsigned w = img.width(); -+ unsigned h = img.height(); -+ unsigned wm = w - 1; -+ unsigned hm = h - 1; -+ -+ unsigned div; -+ unsigned mul_sum; -+ unsigned shr_sum; -+ -+ pod_vector stack; -+ -+ if(rx > 0) -+ { -+ if(rx > 254) rx = 254; -+ div = rx * 2 + 1; -+ mul_sum = stack_blur_tables::g_stack_blur8_mul[rx]; -+ shr_sum = stack_blur_tables::g_stack_blur8_shr[rx]; -+ stack.allocate(div); -+ -+ for(y = 0; y < h; y++) -+ { -+ sum = sum_in = sum_out = 0; -+ -+ src_pix_ptr = img.pix_ptr(0, y); -+ pix = *src_pix_ptr; -+ for(i = 0; i <= rx; i++) -+ { -+ stack[i] = pix; -+ sum += pix * (i + 1); -+ sum_out += pix; -+ } -+ for(i = 1; i <= rx; i++) -+ { -+ if(i <= wm) src_pix_ptr += Img::pix_step; -+ pix = *src_pix_ptr; -+ stack[i + rx] = pix; -+ sum += pix * (rx + 1 - i); -+ sum_in += pix; -+ } -+ -+ stack_ptr = rx; -+ xp = rx; -+ if(xp > wm) xp = wm; -+ src_pix_ptr = img.pix_ptr(xp, y); -+ dst_pix_ptr = img.pix_ptr(0, y); -+ for(x = 0; x < w; x++) -+ { -+ *dst_pix_ptr = (sum * mul_sum) >> shr_sum; -+ dst_pix_ptr += Img::pix_step; -+ -+ sum -= sum_out; -+ -+ stack_start = stack_ptr + div - rx; -+ if(stack_start >= div) stack_start -= div; -+ sum_out -= stack[stack_start]; -+ -+ if(xp < wm) -+ { -+ src_pix_ptr += Img::pix_step; -+ pix = *src_pix_ptr; -+ ++xp; -+ } -+ -+ stack[stack_start] = pix; -+ -+ sum_in += pix; -+ sum += sum_in; -+ -+ ++stack_ptr; -+ if(stack_ptr >= div) stack_ptr = 0; -+ stack_pix = stack[stack_ptr]; -+ -+ sum_out += stack_pix; -+ sum_in -= stack_pix; -+ } -+ } -+ } -+ -+ if(ry > 0) -+ { -+ if(ry > 254) ry = 254; -+ div = ry * 2 + 1; -+ mul_sum = stack_blur_tables::g_stack_blur8_mul[ry]; -+ shr_sum = stack_blur_tables::g_stack_blur8_shr[ry]; -+ stack.allocate(div); -+ -+ int stride = img.stride(); -+ for(x = 0; x < w; x++) -+ { -+ sum = sum_in = sum_out = 0; -+ -+ src_pix_ptr = img.pix_ptr(x, 0); -+ pix = *src_pix_ptr; -+ for(i = 0; i <= ry; i++) -+ { -+ stack[i] = pix; -+ sum += pix * (i + 1); -+ sum_out += pix; -+ } -+ for(i = 1; i <= ry; i++) -+ { -+ if(i <= hm) src_pix_ptr += stride; -+ pix = *src_pix_ptr; -+ stack[i + ry] = pix; -+ sum += pix * (ry + 1 - i); -+ sum_in += pix; -+ } -+ -+ stack_ptr = ry; -+ yp = ry; -+ if(yp > hm) yp = hm; -+ src_pix_ptr = img.pix_ptr(x, yp); -+ dst_pix_ptr = img.pix_ptr(x, 0); -+ for(y = 0; y < h; y++) -+ { -+ *dst_pix_ptr = (sum * mul_sum) >> shr_sum; -+ dst_pix_ptr += stride; -+ -+ sum -= sum_out; -+ -+ stack_start = stack_ptr + div - ry; -+ if(stack_start >= div) stack_start -= div; -+ sum_out -= stack[stack_start]; -+ -+ if(yp < hm) -+ { -+ src_pix_ptr += stride; -+ pix = *src_pix_ptr; -+ ++yp; -+ } -+ -+ stack[stack_start] = pix; -+ -+ sum_in += pix; -+ sum += sum_in; -+ -+ ++stack_ptr; -+ if(stack_ptr >= div) stack_ptr = 0; -+ stack_pix = stack[stack_ptr]; -+ -+ sum_out += stack_pix; -+ sum_in -= stack_pix; -+ } -+ } -+ } -+ } -+ -+ -+ -+ //========================================================stack_blur_rgb24 -+ template -+ void stack_blur_rgb24(Img& img, unsigned rx, unsigned ry) -+ { -+ typedef typename Img::color_type color_type; -+ typedef typename Img::order_type order_type; -+ enum order_e -+ { -+ R = order_type::R, -+ G = order_type::G, -+ B = order_type::B -+ }; -+ -+ unsigned x, y, xp, yp, i; -+ unsigned stack_ptr; -+ unsigned stack_start; -+ -+ const int8u* src_pix_ptr; -+ int8u* dst_pix_ptr; -+ color_type* stack_pix_ptr; -+ -+ unsigned sum_r; -+ unsigned sum_g; -+ unsigned sum_b; -+ unsigned sum_in_r; -+ unsigned sum_in_g; -+ unsigned sum_in_b; -+ unsigned sum_out_r; -+ unsigned sum_out_g; -+ unsigned sum_out_b; -+ -+ unsigned w = img.width(); -+ unsigned h = img.height(); -+ unsigned wm = w - 1; -+ unsigned hm = h - 1; -+ -+ unsigned div; -+ unsigned mul_sum; -+ unsigned shr_sum; -+ -+ pod_vector stack; -+ -+ if(rx > 0) -+ { -+ if(rx > 254) rx = 254; -+ div = rx * 2 + 1; -+ mul_sum = stack_blur_tables::g_stack_blur8_mul[rx]; -+ shr_sum = stack_blur_tables::g_stack_blur8_shr[rx]; -+ stack.allocate(div); -+ -+ for(y = 0; y < h; y++) -+ { -+ sum_r = -+ sum_g = -+ sum_b = -+ sum_in_r = -+ sum_in_g = -+ sum_in_b = -+ sum_out_r = -+ sum_out_g = -+ sum_out_b = 0; -+ -+ src_pix_ptr = img.pix_ptr(0, y); -+ for(i = 0; i <= rx; i++) -+ { -+ stack_pix_ptr = &stack[i]; -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ sum_r += src_pix_ptr[R] * (i + 1); -+ sum_g += src_pix_ptr[G] * (i + 1); -+ sum_b += src_pix_ptr[B] * (i + 1); -+ sum_out_r += src_pix_ptr[R]; -+ sum_out_g += src_pix_ptr[G]; -+ sum_out_b += src_pix_ptr[B]; -+ } -+ for(i = 1; i <= rx; i++) -+ { -+ if(i <= wm) src_pix_ptr += Img::pix_width; -+ stack_pix_ptr = &stack[i + rx]; -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ sum_r += src_pix_ptr[R] * (rx + 1 - i); -+ sum_g += src_pix_ptr[G] * (rx + 1 - i); -+ sum_b += src_pix_ptr[B] * (rx + 1 - i); -+ sum_in_r += src_pix_ptr[R]; -+ sum_in_g += src_pix_ptr[G]; -+ sum_in_b += src_pix_ptr[B]; -+ } -+ -+ stack_ptr = rx; -+ xp = rx; -+ if(xp > wm) xp = wm; -+ src_pix_ptr = img.pix_ptr(xp, y); -+ dst_pix_ptr = img.pix_ptr(0, y); -+ for(x = 0; x < w; x++) -+ { -+ dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; -+ dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; -+ dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; -+ dst_pix_ptr += Img::pix_width; -+ -+ sum_r -= sum_out_r; -+ sum_g -= sum_out_g; -+ sum_b -= sum_out_b; -+ -+ stack_start = stack_ptr + div - rx; -+ if(stack_start >= div) stack_start -= div; -+ stack_pix_ptr = &stack[stack_start]; -+ -+ sum_out_r -= stack_pix_ptr->r; -+ sum_out_g -= stack_pix_ptr->g; -+ sum_out_b -= stack_pix_ptr->b; -+ -+ if(xp < wm) -+ { -+ src_pix_ptr += Img::pix_width; -+ ++xp; -+ } -+ -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ -+ sum_in_r += src_pix_ptr[R]; -+ sum_in_g += src_pix_ptr[G]; -+ sum_in_b += src_pix_ptr[B]; -+ sum_r += sum_in_r; -+ sum_g += sum_in_g; -+ sum_b += sum_in_b; -+ -+ ++stack_ptr; -+ if(stack_ptr >= div) stack_ptr = 0; -+ stack_pix_ptr = &stack[stack_ptr]; -+ -+ sum_out_r += stack_pix_ptr->r; -+ sum_out_g += stack_pix_ptr->g; -+ sum_out_b += stack_pix_ptr->b; -+ sum_in_r -= stack_pix_ptr->r; -+ sum_in_g -= stack_pix_ptr->g; -+ sum_in_b -= stack_pix_ptr->b; -+ } -+ } -+ } -+ -+ if(ry > 0) -+ { -+ if(ry > 254) ry = 254; -+ div = ry * 2 + 1; -+ mul_sum = stack_blur_tables::g_stack_blur8_mul[ry]; -+ shr_sum = stack_blur_tables::g_stack_blur8_shr[ry]; -+ stack.allocate(div); -+ -+ int stride = img.stride(); -+ for(x = 0; x < w; x++) -+ { -+ sum_r = -+ sum_g = -+ sum_b = -+ sum_in_r = -+ sum_in_g = -+ sum_in_b = -+ sum_out_r = -+ sum_out_g = -+ sum_out_b = 0; -+ -+ src_pix_ptr = img.pix_ptr(x, 0); -+ for(i = 0; i <= ry; i++) -+ { -+ stack_pix_ptr = &stack[i]; -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ sum_r += src_pix_ptr[R] * (i + 1); -+ sum_g += src_pix_ptr[G] * (i + 1); -+ sum_b += src_pix_ptr[B] * (i + 1); -+ sum_out_r += src_pix_ptr[R]; -+ sum_out_g += src_pix_ptr[G]; -+ sum_out_b += src_pix_ptr[B]; -+ } -+ for(i = 1; i <= ry; i++) -+ { -+ if(i <= hm) src_pix_ptr += stride; -+ stack_pix_ptr = &stack[i + ry]; -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ sum_r += src_pix_ptr[R] * (ry + 1 - i); -+ sum_g += src_pix_ptr[G] * (ry + 1 - i); -+ sum_b += src_pix_ptr[B] * (ry + 1 - i); -+ sum_in_r += src_pix_ptr[R]; -+ sum_in_g += src_pix_ptr[G]; -+ sum_in_b += src_pix_ptr[B]; -+ } -+ -+ stack_ptr = ry; -+ yp = ry; -+ if(yp > hm) yp = hm; -+ src_pix_ptr = img.pix_ptr(x, yp); -+ dst_pix_ptr = img.pix_ptr(x, 0); -+ for(y = 0; y < h; y++) -+ { -+ dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; -+ dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; -+ dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; -+ dst_pix_ptr += stride; -+ -+ sum_r -= sum_out_r; -+ sum_g -= sum_out_g; -+ sum_b -= sum_out_b; -+ -+ stack_start = stack_ptr + div - ry; -+ if(stack_start >= div) stack_start -= div; -+ -+ stack_pix_ptr = &stack[stack_start]; -+ sum_out_r -= stack_pix_ptr->r; -+ sum_out_g -= stack_pix_ptr->g; -+ sum_out_b -= stack_pix_ptr->b; -+ -+ if(yp < hm) -+ { -+ src_pix_ptr += stride; -+ ++yp; -+ } -+ -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ -+ sum_in_r += src_pix_ptr[R]; -+ sum_in_g += src_pix_ptr[G]; -+ sum_in_b += src_pix_ptr[B]; -+ sum_r += sum_in_r; -+ sum_g += sum_in_g; -+ sum_b += sum_in_b; -+ -+ ++stack_ptr; -+ if(stack_ptr >= div) stack_ptr = 0; -+ stack_pix_ptr = &stack[stack_ptr]; -+ -+ sum_out_r += stack_pix_ptr->r; -+ sum_out_g += stack_pix_ptr->g; -+ sum_out_b += stack_pix_ptr->b; -+ sum_in_r -= stack_pix_ptr->r; -+ sum_in_g -= stack_pix_ptr->g; -+ sum_in_b -= stack_pix_ptr->b; -+ } -+ } -+ } -+ } -+ -+ -+ -+ //=======================================================stack_blur_rgba32 -+ template -+ void stack_blur_rgba32(Img& img, unsigned rx, unsigned ry) -+ { -+ typedef typename Img::color_type color_type; -+ typedef typename Img::order_type order_type; -+ enum order_e -+ { -+ R = order_type::R, -+ G = order_type::G, -+ B = order_type::B, -+ A = order_type::A -+ }; -+ -+ unsigned x, y, xp, yp, i; -+ unsigned stack_ptr; -+ unsigned stack_start; -+ -+ const int8u* src_pix_ptr; -+ int8u* dst_pix_ptr; -+ color_type* stack_pix_ptr; -+ -+ unsigned sum_r; -+ unsigned sum_g; -+ unsigned sum_b; -+ unsigned sum_a; -+ unsigned sum_in_r; -+ unsigned sum_in_g; -+ unsigned sum_in_b; -+ unsigned sum_in_a; -+ unsigned sum_out_r; -+ unsigned sum_out_g; -+ unsigned sum_out_b; -+ unsigned sum_out_a; -+ -+ unsigned w = img.width(); -+ unsigned h = img.height(); -+ unsigned wm = w - 1; -+ unsigned hm = h - 1; -+ -+ unsigned div; -+ unsigned mul_sum; -+ unsigned shr_sum; -+ -+ pod_vector stack; -+ -+ if(rx > 0) -+ { -+ if(rx > 254) rx = 254; -+ div = rx * 2 + 1; -+ mul_sum = stack_blur_tables::g_stack_blur8_mul[rx]; -+ shr_sum = stack_blur_tables::g_stack_blur8_shr[rx]; -+ stack.allocate(div); -+ -+ for(y = 0; y < h; y++) -+ { -+ sum_r = -+ sum_g = -+ sum_b = -+ sum_a = -+ sum_in_r = -+ sum_in_g = -+ sum_in_b = -+ sum_in_a = -+ sum_out_r = -+ sum_out_g = -+ sum_out_b = -+ sum_out_a = 0; -+ -+ src_pix_ptr = img.pix_ptr(0, y); -+ for(i = 0; i <= rx; i++) -+ { -+ stack_pix_ptr = &stack[i]; -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ stack_pix_ptr->a = src_pix_ptr[A]; -+ sum_r += src_pix_ptr[R] * (i + 1); -+ sum_g += src_pix_ptr[G] * (i + 1); -+ sum_b += src_pix_ptr[B] * (i + 1); -+ sum_a += src_pix_ptr[A] * (i + 1); -+ sum_out_r += src_pix_ptr[R]; -+ sum_out_g += src_pix_ptr[G]; -+ sum_out_b += src_pix_ptr[B]; -+ sum_out_a += src_pix_ptr[A]; -+ } -+ for(i = 1; i <= rx; i++) -+ { -+ if(i <= wm) src_pix_ptr += Img::pix_width; -+ stack_pix_ptr = &stack[i + rx]; -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ stack_pix_ptr->a = src_pix_ptr[A]; -+ sum_r += src_pix_ptr[R] * (rx + 1 - i); -+ sum_g += src_pix_ptr[G] * (rx + 1 - i); -+ sum_b += src_pix_ptr[B] * (rx + 1 - i); -+ sum_a += src_pix_ptr[A] * (rx + 1 - i); -+ sum_in_r += src_pix_ptr[R]; -+ sum_in_g += src_pix_ptr[G]; -+ sum_in_b += src_pix_ptr[B]; -+ sum_in_a += src_pix_ptr[A]; -+ } -+ -+ stack_ptr = rx; -+ xp = rx; -+ if(xp > wm) xp = wm; -+ src_pix_ptr = img.pix_ptr(xp, y); -+ dst_pix_ptr = img.pix_ptr(0, y); -+ for(x = 0; x < w; x++) -+ { -+ dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; -+ dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; -+ dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; -+ dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum; -+ dst_pix_ptr += Img::pix_width; -+ -+ sum_r -= sum_out_r; -+ sum_g -= sum_out_g; -+ sum_b -= sum_out_b; -+ sum_a -= sum_out_a; -+ -+ stack_start = stack_ptr + div - rx; -+ if(stack_start >= div) stack_start -= div; -+ stack_pix_ptr = &stack[stack_start]; -+ -+ sum_out_r -= stack_pix_ptr->r; -+ sum_out_g -= stack_pix_ptr->g; -+ sum_out_b -= stack_pix_ptr->b; -+ sum_out_a -= stack_pix_ptr->a; -+ -+ if(xp < wm) -+ { -+ src_pix_ptr += Img::pix_width; -+ ++xp; -+ } -+ -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ stack_pix_ptr->a = src_pix_ptr[A]; -+ -+ sum_in_r += src_pix_ptr[R]; -+ sum_in_g += src_pix_ptr[G]; -+ sum_in_b += src_pix_ptr[B]; -+ sum_in_a += src_pix_ptr[A]; -+ sum_r += sum_in_r; -+ sum_g += sum_in_g; -+ sum_b += sum_in_b; -+ sum_a += sum_in_a; -+ -+ ++stack_ptr; -+ if(stack_ptr >= div) stack_ptr = 0; -+ stack_pix_ptr = &stack[stack_ptr]; -+ -+ sum_out_r += stack_pix_ptr->r; -+ sum_out_g += stack_pix_ptr->g; -+ sum_out_b += stack_pix_ptr->b; -+ sum_out_a += stack_pix_ptr->a; -+ sum_in_r -= stack_pix_ptr->r; -+ sum_in_g -= stack_pix_ptr->g; -+ sum_in_b -= stack_pix_ptr->b; -+ sum_in_a -= stack_pix_ptr->a; -+ } -+ } -+ } -+ -+ if(ry > 0) -+ { -+ if(ry > 254) ry = 254; -+ div = ry * 2 + 1; -+ mul_sum = stack_blur_tables::g_stack_blur8_mul[ry]; -+ shr_sum = stack_blur_tables::g_stack_blur8_shr[ry]; -+ stack.allocate(div); -+ -+ int stride = img.stride(); -+ for(x = 0; x < w; x++) -+ { -+ sum_r = -+ sum_g = -+ sum_b = -+ sum_a = -+ sum_in_r = -+ sum_in_g = -+ sum_in_b = -+ sum_in_a = -+ sum_out_r = -+ sum_out_g = -+ sum_out_b = -+ sum_out_a = 0; -+ -+ src_pix_ptr = img.pix_ptr(x, 0); -+ for(i = 0; i <= ry; i++) -+ { -+ stack_pix_ptr = &stack[i]; -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ stack_pix_ptr->a = src_pix_ptr[A]; -+ sum_r += src_pix_ptr[R] * (i + 1); -+ sum_g += src_pix_ptr[G] * (i + 1); -+ sum_b += src_pix_ptr[B] * (i + 1); -+ sum_a += src_pix_ptr[A] * (i + 1); -+ sum_out_r += src_pix_ptr[R]; -+ sum_out_g += src_pix_ptr[G]; -+ sum_out_b += src_pix_ptr[B]; -+ sum_out_a += src_pix_ptr[A]; -+ } -+ for(i = 1; i <= ry; i++) -+ { -+ if(i <= hm) src_pix_ptr += stride; -+ stack_pix_ptr = &stack[i + ry]; -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ stack_pix_ptr->a = src_pix_ptr[A]; -+ sum_r += src_pix_ptr[R] * (ry + 1 - i); -+ sum_g += src_pix_ptr[G] * (ry + 1 - i); -+ sum_b += src_pix_ptr[B] * (ry + 1 - i); -+ sum_a += src_pix_ptr[A] * (ry + 1 - i); -+ sum_in_r += src_pix_ptr[R]; -+ sum_in_g += src_pix_ptr[G]; -+ sum_in_b += src_pix_ptr[B]; -+ sum_in_a += src_pix_ptr[A]; -+ } -+ -+ stack_ptr = ry; -+ yp = ry; -+ if(yp > hm) yp = hm; -+ src_pix_ptr = img.pix_ptr(x, yp); -+ dst_pix_ptr = img.pix_ptr(x, 0); -+ for(y = 0; y < h; y++) -+ { -+ dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; -+ dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; -+ dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; -+ dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum; -+ dst_pix_ptr += stride; -+ -+ sum_r -= sum_out_r; -+ sum_g -= sum_out_g; -+ sum_b -= sum_out_b; -+ sum_a -= sum_out_a; -+ -+ stack_start = stack_ptr + div - ry; -+ if(stack_start >= div) stack_start -= div; -+ -+ stack_pix_ptr = &stack[stack_start]; -+ sum_out_r -= stack_pix_ptr->r; -+ sum_out_g -= stack_pix_ptr->g; -+ sum_out_b -= stack_pix_ptr->b; -+ sum_out_a -= stack_pix_ptr->a; -+ -+ if(yp < hm) -+ { -+ src_pix_ptr += stride; -+ ++yp; -+ } -+ -+ stack_pix_ptr->r = src_pix_ptr[R]; -+ stack_pix_ptr->g = src_pix_ptr[G]; -+ stack_pix_ptr->b = src_pix_ptr[B]; -+ stack_pix_ptr->a = src_pix_ptr[A]; -+ -+ sum_in_r += src_pix_ptr[R]; -+ sum_in_g += src_pix_ptr[G]; -+ sum_in_b += src_pix_ptr[B]; -+ sum_in_a += src_pix_ptr[A]; -+ sum_r += sum_in_r; -+ sum_g += sum_in_g; -+ sum_b += sum_in_b; -+ sum_a += sum_in_a; -+ -+ ++stack_ptr; -+ if(stack_ptr >= div) stack_ptr = 0; -+ stack_pix_ptr = &stack[stack_ptr]; -+ -+ sum_out_r += stack_pix_ptr->r; -+ sum_out_g += stack_pix_ptr->g; -+ sum_out_b += stack_pix_ptr->b; -+ sum_out_a += stack_pix_ptr->a; -+ sum_in_r -= stack_pix_ptr->r; -+ sum_in_g -= stack_pix_ptr->g; -+ sum_in_b -= stack_pix_ptr->b; -+ sum_in_a -= stack_pix_ptr->a; -+ } -+ } -+ } -+ } -+ -+ -+ -+ //===========================================================recursive_blur -+ template class recursive_blur -+ { -+ public: -+ typedef ColorT color_type; -+ typedef CalculatorT calculator_type; -+ typedef typename color_type::value_type value_type; -+ typedef typename calculator_type::value_type calc_type; -+ -+ //-------------------------------------------------------------------- -+ template void blur_x(Img& img, double radius) -+ { -+ if(radius < 0.62) return; -+ if(img.width() < 3) return; -+ -+ calc_type s = calc_type(radius * 0.5); -+ calc_type q = calc_type((s < 2.5) ? -+ 3.97156 - 4.14554 * sqrt(1 - 0.26891 * s) : -+ 0.98711 * s - 0.96330); -+ -+ calc_type q2 = calc_type(q * q); -+ calc_type q3 = calc_type(q2 * q); -+ -+ calc_type b0 = calc_type(1.0 / (1.578250 + -+ 2.444130 * q + -+ 1.428100 * q2 + -+ 0.422205 * q3)); -+ -+ calc_type b1 = calc_type( 2.44413 * q + -+ 2.85619 * q2 + -+ 1.26661 * q3); -+ -+ calc_type b2 = calc_type(-1.42810 * q2 + -+ -1.26661 * q3); -+ -+ calc_type b3 = calc_type(0.422205 * q3); -+ -+ calc_type b = calc_type(1 - (b1 + b2 + b3) * b0); -+ -+ b1 *= b0; -+ b2 *= b0; -+ b3 *= b0; -+ -+ int w = img.width(); -+ int h = img.height(); -+ int wm = w-1; -+ int x, y; -+ -+ m_sum1.allocate(w); -+ m_sum2.allocate(w); -+ m_buf.allocate(w); -+ -+ for(y = 0; y < h; y++) -+ { -+ calculator_type c; -+ c.from_pix(img.pixel(0, y)); -+ m_sum1[0].calc(b, b1, b2, b3, c, c, c, c); -+ c.from_pix(img.pixel(1, y)); -+ m_sum1[1].calc(b, b1, b2, b3, c, m_sum1[0], m_sum1[0], m_sum1[0]); -+ c.from_pix(img.pixel(2, y)); -+ m_sum1[2].calc(b, b1, b2, b3, c, m_sum1[1], m_sum1[0], m_sum1[0]); -+ -+ for(x = 3; x < w; ++x) -+ { -+ c.from_pix(img.pixel(x, y)); -+ m_sum1[x].calc(b, b1, b2, b3, c, m_sum1[x-1], m_sum1[x-2], m_sum1[x-3]); -+ } -+ -+ m_sum2[wm ].calc(b, b1, b2, b3, m_sum1[wm ], m_sum1[wm ], m_sum1[wm], m_sum1[wm]); -+ m_sum2[wm-1].calc(b, b1, b2, b3, m_sum1[wm-1], m_sum2[wm ], m_sum2[wm], m_sum2[wm]); -+ m_sum2[wm-2].calc(b, b1, b2, b3, m_sum1[wm-2], m_sum2[wm-1], m_sum2[wm], m_sum2[wm]); -+ m_sum2[wm ].to_pix(m_buf[wm ]); -+ m_sum2[wm-1].to_pix(m_buf[wm-1]); -+ m_sum2[wm-2].to_pix(m_buf[wm-2]); -+ -+ for(x = wm-3; x >= 0; --x) -+ { -+ m_sum2[x].calc(b, b1, b2, b3, m_sum1[x], m_sum2[x+1], m_sum2[x+2], m_sum2[x+3]); -+ m_sum2[x].to_pix(m_buf[x]); -+ } -+ img.copy_color_hspan(0, y, w, &m_buf[0]); -+ } -+ } -+ -+ //-------------------------------------------------------------------- -+ template void blur_y(Img& img, double radius) -+ { -+ pixfmt_transposer img2(img); -+ blur_x(img2, radius); -+ } -+ -+ //-------------------------------------------------------------------- -+ template void blur(Img& img, double radius) -+ { -+ blur_x(img, radius); -+ pixfmt_transposer img2(img); -+ blur_x(img2, radius); -+ } -+ -+ private: -+ agg::pod_vector m_sum1; -+ agg::pod_vector m_sum2; -+ agg::pod_vector m_buf; -+ }; -+ -+ -+ //=================================================recursive_blur_calc_rgba -+ template struct recursive_blur_calc_rgba -+ { -+ typedef T value_type; -+ typedef recursive_blur_calc_rgba self_type; -+ -+ value_type r,g,b,a; -+ -+ template -+ AGG_INLINE void from_pix(const ColorT& c) -+ { -+ r = c.r; -+ g = c.g; -+ b = c.b; -+ a = c.a; -+ } -+ -+ AGG_INLINE void calc(value_type b1, -+ value_type b2, -+ value_type b3, -+ value_type b4, -+ const self_type& c1, -+ const self_type& c2, -+ const self_type& c3, -+ const self_type& c4) -+ { -+ r = b1*c1.r + b2*c2.r + b3*c3.r + b4*c4.r; -+ g = b1*c1.g + b2*c2.g + b3*c3.g + b4*c4.g; -+ b = b1*c1.b + b2*c2.b + b3*c3.b + b4*c4.b; -+ a = b1*c1.a + b2*c2.a + b3*c3.a + b4*c4.a; -+ } -+ -+ template -+ AGG_INLINE void to_pix(ColorT& c) const -+ { -+ typedef typename ColorT::value_type cv_type; -+ c.r = (cv_type)uround(r); -+ c.g = (cv_type)uround(g); -+ c.b = (cv_type)uround(b); -+ c.a = (cv_type)uround(a); -+ } -+ }; -+ -+ -+ //=================================================recursive_blur_calc_rgb -+ template struct recursive_blur_calc_rgb -+ { -+ typedef T value_type; -+ typedef recursive_blur_calc_rgb self_type; -+ -+ value_type r,g,b; -+ -+ template -+ AGG_INLINE void from_pix(const ColorT& c) -+ { -+ r = c.r; -+ g = c.g; -+ b = c.b; -+ } -+ -+ AGG_INLINE void calc(value_type b1, -+ value_type b2, -+ value_type b3, -+ value_type b4, -+ const self_type& c1, -+ const self_type& c2, -+ const self_type& c3, -+ const self_type& c4) -+ { -+ r = b1*c1.r + b2*c2.r + b3*c3.r + b4*c4.r; -+ g = b1*c1.g + b2*c2.g + b3*c3.g + b4*c4.g; -+ b = b1*c1.b + b2*c2.b + b3*c3.b + b4*c4.b; -+ } -+ -+ template -+ AGG_INLINE void to_pix(ColorT& c) const -+ { -+ typedef typename ColorT::value_type cv_type; -+ c.r = (cv_type)uround(r); -+ c.g = (cv_type)uround(g); -+ c.b = (cv_type)uround(b); -+ } -+ }; -+ -+ -+ //================================================recursive_blur_calc_gray -+ template struct recursive_blur_calc_gray -+ { -+ typedef T value_type; -+ typedef recursive_blur_calc_gray self_type; -+ -+ value_type v; -+ -+ template -+ AGG_INLINE void from_pix(const ColorT& c) -+ { -+ v = c.v; -+ } -+ -+ AGG_INLINE void calc(value_type b1, -+ value_type b2, -+ value_type b3, -+ value_type b4, -+ const self_type& c1, -+ const self_type& c2, -+ const self_type& c3, -+ const self_type& c4) -+ { -+ v = b1*c1.v + b2*c2.v + b3*c3.v + b4*c4.v; -+ } -+ -+ template -+ AGG_INLINE void to_pix(ColorT& c) const -+ { -+ typedef typename ColorT::value_type cv_type; -+ c.v = (cv_type)uround(v); -+ } -+ }; -+ -+} -+ -+ -+ -+ -+#endif -diff --git a/src/third_party/agg/include/agg_bspline.h b/src/third_party/agg/include/agg_bspline.h -index 19a153f..2c1ed9a 100644 ---- a/src/third_party/agg/include/agg_bspline.h -+++ b/src/third_party/agg/include/agg_bspline.h -@@ -20,7 +20,7 @@ - #ifndef AGG_BSPLINE_INCLUDED - #define AGG_BSPLINE_INCLUDED - --#include "agg_basics.h" -+#include "agg_array.h" - - namespace agg - { -@@ -40,7 +40,6 @@ namespace agg - class bspline - { - public: -- ~bspline(); - bspline(); - bspline(int num); - bspline(int num, const double* x, const double* y); -@@ -63,12 +62,12 @@ namespace agg - double extrapolation_right(double x) const; - double interpolation(double x, int i) const; - -- int m_max; -- int m_num; -- double* m_x; -- double* m_y; -- double* m_am; -- mutable int m_last_idx; -+ int m_max; -+ int m_num; -+ double* m_x; -+ double* m_y; -+ pod_array m_am; -+ mutable int m_last_idx; - }; - - -diff --git a/src/third_party/agg/include/agg_color_gray.h b/src/third_party/agg/include/agg_color_gray.h -index 0fb11cc..5fa44ce 100644 ---- a/src/third_party/agg/include/agg_color_gray.h -+++ b/src/third_party/agg/include/agg_color_gray.h -@@ -55,7 +55,7 @@ namespace agg - gray8() {} - - //-------------------------------------------------------------------- -- gray8(unsigned v_, unsigned a_=base_mask) : -+ explicit gray8(unsigned v_, unsigned a_=base_mask) : - v(int8u(v_)), a(int8u(a_)) {} - - //-------------------------------------------------------------------- -@@ -162,6 +162,31 @@ namespace agg - return ret; - } - -+ //-------------------------------------------------------------------- -+ AGG_INLINE void add(const self_type& c, unsigned cover) -+ { -+ calc_type cv, ca; -+ if(cover == cover_mask) -+ { -+ if(c.a == base_mask) -+ { -+ *this = c; -+ } -+ else -+ { -+ cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; -+ ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; -+ } -+ } -+ else -+ { -+ cv = v + ((c.v * cover + cover_mask/2) >> cover_shift); -+ ca = a + ((c.a * cover + cover_mask/2) >> cover_shift); -+ v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; -+ a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; -+ } -+ } -+ - //-------------------------------------------------------------------- - static self_type no_color() { return self_type(0,0); } - }; -@@ -217,7 +242,7 @@ namespace agg - gray16() {} - - //-------------------------------------------------------------------- -- gray16(unsigned v_, unsigned a_=base_mask) : -+ explicit gray16(unsigned v_, unsigned a_=base_mask) : - v(int16u(v_)), a(int16u(a_)) {} - - //-------------------------------------------------------------------- -@@ -324,6 +349,31 @@ namespace agg - return ret; - } - -+ //-------------------------------------------------------------------- -+ AGG_INLINE void add(const self_type& c, unsigned cover) -+ { -+ calc_type cv, ca; -+ if(cover == cover_mask) -+ { -+ if(c.a == base_mask) -+ { -+ *this = c; -+ } -+ else -+ { -+ cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; -+ ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; -+ } -+ } -+ else -+ { -+ cv = v + ((c.v * cover + cover_mask/2) >> cover_shift); -+ ca = a + ((c.a * cover + cover_mask/2) >> cover_shift); -+ v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; -+ a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; -+ } -+ } -+ - //-------------------------------------------------------------------- - static self_type no_color() { return self_type(0,0); } - }; -diff --git a/src/third_party/agg/include/agg_conv_adaptor_vcgen.h b/src/third_party/agg/include/agg_conv_adaptor_vcgen.h -index 45811e6..cee24b2 100644 ---- a/src/third_party/agg/include/agg_conv_adaptor_vcgen.h -+++ b/src/third_party/agg/include/agg_conv_adaptor_vcgen.h -@@ -49,8 +49,7 @@ namespace agg - m_source(&source), - m_status(initial) - {} -- -- void set_source(VertexSource& source) { m_source = &source; } -+ void attach(VertexSource& source) { m_source = &source; } - - Generator& generator() { return m_generator; } - const Generator& generator() const { return m_generator; } -diff --git a/src/third_party/agg/include/agg_conv_adaptor_vpgen.h b/src/third_party/agg/include/agg_conv_adaptor_vpgen.h -index 37d9730..8fcedcb 100644 ---- a/src/third_party/agg/include/agg_conv_adaptor_vpgen.h -+++ b/src/third_party/agg/include/agg_conv_adaptor_vpgen.h -@@ -26,8 +26,7 @@ namespace agg - { - public: - conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {} -- -- void set_source(VertexSource& source) { m_source = &source; } -+ void attach(VertexSource& source) { m_source = &source; } - - VPGen& vpgen() { return m_vpgen; } - const VPGen& vpgen() const { return m_vpgen; } -diff --git a/src/third_party/agg/include/agg_conv_close_polygon.h b/src/third_party/agg/include/agg_conv_close_polygon.h -index d8f054c..7eecc9c 100644 ---- a/src/third_party/agg/include/agg_conv_close_polygon.h -+++ b/src/third_party/agg/include/agg_conv_close_polygon.h -@@ -26,8 +26,7 @@ namespace agg - { - public: - conv_close_polygon(VertexSource& vs) : m_source(&vs) {} -- -- void set_source(VertexSource& source) { m_source = &source; } -+ void attach(VertexSource& source) { m_source = &source; } - - void rewind(unsigned path_id); - unsigned vertex(double* x, double* y); -diff --git a/src/third_party/agg/include/agg_conv_concat.h b/src/third_party/agg/include/agg_conv_concat.h -index fd243b4..745d349 100644 ---- a/src/third_party/agg/include/agg_conv_concat.h -+++ b/src/third_party/agg/include/agg_conv_concat.h -@@ -28,9 +28,8 @@ namespace agg - public: - conv_concat(VS1& source1, VS2& source2) : - m_source1(&source1), m_source2(&source2), m_status(2) {} -- -- void set_source1(VS1& source) { m_source1 = &source; } -- void set_source2(VS2& source) { m_source2 = &source; } -+ void attach1(VS1& source) { m_source1 = &source; } -+ void attach2(VS2& source) { m_source2 = &source; } - - - void rewind(unsigned path_id) -diff --git a/src/third_party/agg/include/agg_conv_curve.h b/src/third_party/agg/include/agg_conv_curve.h -index 5308b1a..bc28691 100644 ---- a/src/third_party/agg/include/agg_conv_curve.h -+++ b/src/third_party/agg/include/agg_conv_curve.h -@@ -23,6 +23,9 @@ - #include "agg_basics.h" - #include "agg_curves.h" - -+#include -+ -+ - namespace agg - { - -@@ -62,8 +65,7 @@ namespace agg - - conv_curve(VertexSource& source) : - m_source(&source), m_last_x(0.0), m_last_y(0.0) {} -- -- void set_source(VertexSource& source) { m_source = &source; } -+ void attach(VertexSource& source) { m_source = &source; } - - void approximation_method(curve_approximation_method_e v) - { -@@ -155,30 +157,26 @@ namespace agg - return path_cmd_line_to; - } - -- double ct2_x; -- double ct2_y; -- double end_x; -- double end_y; -+ double ct2_x = 0; -+ double ct2_y = 0; -+ double end_x = 0; -+ double end_y = 0; - - unsigned cmd = m_source->vertex(x, y); - switch(cmd) - { -- case path_cmd_move_to: -- case path_cmd_line_to: -- m_last_x = *x; -- m_last_y = *y; -- default: -- break; -- - case path_cmd_curve3: - m_source->vertex(&end_x, &end_y); - -- m_curve3.init(m_last_x, m_last_y, -- *x, *y, -- end_x, end_y); -+ if (!std::isnan(m_last_x) && !std::isnan(m_last_y) && !std::isnan(*x) -+ && !std::isnan(*y) && !std::isnan(end_x) && !std::isnan(end_y)) { -+ m_curve3.init(m_last_x, m_last_y, -+ *x, *y, -+ end_x, end_y); - -- m_curve3.vertex(x, y); // First call returns path_cmd_move_to -- m_curve3.vertex(x, y); // This is the first vertex of the curve -+ m_curve3.vertex(x, y); // First call returns path_cmd_move_to -+ m_curve3.vertex(x, y); // This is the first vertex of the curve -+ } - cmd = path_cmd_line_to; - break; - -@@ -186,16 +184,21 @@ namespace agg - m_source->vertex(&ct2_x, &ct2_y); - m_source->vertex(&end_x, &end_y); - -- m_curve4.init(m_last_x, m_last_y, -- *x, *y, -- ct2_x, ct2_y, -- end_x, end_y); -+ if (!std::isnan(m_last_x) && !std::isnan(m_last_y) && !std::isnan(*x) -+ && !std::isnan(*y) && !std::isnan(end_x) && !std::isnan(end_y)) { -+ m_curve4.init(m_last_x, m_last_y, -+ *x, *y, -+ ct2_x, ct2_y, -+ end_x, end_y); - -- m_curve4.vertex(x, y); // First call returns path_cmd_move_to -- m_curve4.vertex(x, y); // This is the first vertex of the curve -+ m_curve4.vertex(x, y); // First call returns path_cmd_move_to -+ m_curve4.vertex(x, y); // This is the first vertex of the curve -+ } - cmd = path_cmd_line_to; - break; - } -+ m_last_x = *x; -+ m_last_y = *y; - return cmd; - } - -diff --git a/src/third_party/agg/include/agg_conv_gpc.h b/src/third_party/agg/include/agg_conv_gpc.h -deleted file mode 100644 -index 7d4d65d..0000000 ---- a/src/third_party/agg/include/agg_conv_gpc.h -+++ /dev/null -@@ -1,437 +0,0 @@ --//---------------------------------------------------------------------------- --// Anti-Grain Geometry - Version 2.4 --// Copyright (C) 2002-2005 Maxim Shemanarev (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 --//---------------------------------------------------------------------------- --// --// General Polygon Clipper based on the GPC library by Alan Murta --// Union, Intersection, XOR, A-B, B-A --// Contact the author if you intend to use it in commercial applications! --// http://www.cs.man.ac.uk/aig/staff/alan/software/ --// Alan Murta (email: gpc@cs.man.ac.uk) --// --//---------------------------------------------------------------------------- -- --#ifndef AGG_CONV_GPC_INCLUDED --#define AGG_CONV_GPC_INCLUDED -- --#include --#include "agg_basics.h" --#include "agg_array.h" -- --extern "C" --{ --#include "gpc.h" --} -- --namespace agg --{ -- enum gpc_op_e -- { -- gpc_or, -- gpc_and, -- gpc_xor, -- gpc_a_minus_b, -- gpc_b_minus_a -- }; -- -- -- //================================================================conv_gpc -- template class conv_gpc -- { -- enum status -- { -- status_move_to, -- status_line_to, -- status_stop -- }; -- -- struct contour_header_type -- { -- int num_vertices; -- int hole_flag; -- gpc_vertex* vertices; -- }; -- -- typedef pod_bvector vertex_array_type; -- typedef pod_bvector contour_header_array_type; -- -- -- public: -- typedef VSA source_a_type; -- typedef VSB source_b_type; -- typedef conv_gpc self_type; -- -- ~conv_gpc() -- { -- free_gpc_data(); -- } -- -- conv_gpc(source_a_type& a, source_b_type& b, gpc_op_e op = gpc_or) : -- m_src_a(&a), -- m_src_b(&b), -- m_status(status_move_to), -- m_vertex(-1), -- m_contour(-1), -- m_operation(op) -- { -- memset(&m_poly_a, 0, sizeof(m_poly_a)); -- memset(&m_poly_b, 0, sizeof(m_poly_b)); -- memset(&m_result, 0, sizeof(m_result)); -- } -- -- void set_source1(VSA& source) { m_src_a = &source; } -- void set_source2(VSB& source) { m_src_b = &source; } -- -- void operation(gpc_op_e v) { m_operation = v; } -- -- // Vertex Source Interface -- void rewind(unsigned path_id); -- unsigned vertex(double* x, double* y); -- -- private: -- conv_gpc(const conv_gpc&); -- const conv_gpc& operator = (const conv_gpc&); -- -- //-------------------------------------------------------------------- -- void free_polygon(gpc_polygon& p); -- void free_result(); -- void free_gpc_data(); -- void start_contour(); -- void add_vertex(double x, double y); -- void end_contour(unsigned orientation); -- void make_polygon(gpc_polygon& p); -- void start_extracting(); -- bool next_contour(); -- bool next_vertex(double* x, double* y); -- -- -- //-------------------------------------------------------------------- -- template void add(VS& src, gpc_polygon& p) -- { -- unsigned cmd; -- double x, y; -- double start_x = 0.0; -- double start_y = 0.0; -- bool line_to = false; -- unsigned orientation = 0; -- -- m_contour_accumulator.remove_all(); -- -- while(!is_stop(cmd = src.vertex(&x, &y))) -- { -- if(is_vertex(cmd)) -- { -- if(is_move_to(cmd)) -- { -- if(line_to) -- { -- end_contour(orientation); -- orientation = 0; -- } -- start_contour(); -- start_x = x; -- start_y = y; -- } -- add_vertex(x, y); -- line_to = true; -- } -- else -- { -- if(is_end_poly(cmd)) -- { -- orientation = get_orientation(cmd); -- if(line_to && is_closed(cmd)) -- { -- add_vertex(start_x, start_y); -- } -- } -- } -- } -- if(line_to) -- { -- end_contour(orientation); -- } -- make_polygon(p); -- } -- -- -- private: -- //-------------------------------------------------------------------- -- source_a_type* m_src_a; -- source_b_type* m_src_b; -- status m_status; -- int m_vertex; -- int m_contour; -- gpc_op_e m_operation; -- vertex_array_type m_vertex_accumulator; -- contour_header_array_type m_contour_accumulator; -- gpc_polygon m_poly_a; -- gpc_polygon m_poly_b; -- gpc_polygon m_result; -- }; -- -- -- -- -- -- //------------------------------------------------------------------------ -- template -- void conv_gpc::free_polygon(gpc_polygon& p) -- { -- int i; -- for(i = 0; i < p.num_contours; i++) -- { -- delete [] p.contour[i].vertex; -- } -- delete [] p.hole; -- delete [] p.contour; -- memset(&p, 0, sizeof(gpc_polygon)); -- } -- -- -- //------------------------------------------------------------------------ -- template -- void conv_gpc::free_result() -- { -- if(m_result.contour) -- { -- gpc_free_polygon(&m_result); -- } -- memset(&m_result, 0, sizeof(m_result)); -- } -- -- -- //------------------------------------------------------------------------ -- template -- void conv_gpc::free_gpc_data() -- { -- free_polygon(m_poly_a); -- free_polygon(m_poly_b); -- free_result(); -- } -- -- -- //------------------------------------------------------------------------ -- template -- void conv_gpc::start_contour() -- { -- contour_header_type h; -- memset(&h, 0, sizeof(h)); -- m_contour_accumulator.add(h); -- m_vertex_accumulator.remove_all(); -- } -- -- -- //------------------------------------------------------------------------ -- template -- inline void conv_gpc::add_vertex(double x, double y) -- { -- gpc_vertex v; -- v.x = x; -- v.y = y; -- m_vertex_accumulator.add(v); -- } -- -- -- //------------------------------------------------------------------------ -- template -- void conv_gpc::end_contour(unsigned orientation) -- { -- if(m_contour_accumulator.size()) -- { -- if(m_vertex_accumulator.size() > 2) -- { -- contour_header_type& h = -- m_contour_accumulator[m_contour_accumulator.size() - 1]; -- -- h.num_vertices = m_vertex_accumulator.size(); -- h.hole_flag = 0; -- -- // TO DO: Clarify the "holes" -- //if(is_cw(orientation)) h.hole_flag = 1; -- -- h.vertices = new gpc_vertex [h.num_vertices]; -- gpc_vertex* d = h.vertices; -- int i; -- for(i = 0; i < h.num_vertices; i++) -- { -- const gpc_vertex& s = m_vertex_accumulator[i]; -- d->x = s.x; -- d->y = s.y; -- ++d; -- } -- } -- else -- { -- m_vertex_accumulator.remove_last(); -- } -- } -- } -- -- -- //------------------------------------------------------------------------ -- template -- void conv_gpc::make_polygon(gpc_polygon& p) -- { -- free_polygon(p); -- if(m_contour_accumulator.size()) -- { -- p.num_contours = m_contour_accumulator.size(); -- -- // TO DO: Clarify the "holes" -- //p.hole = new int[p.num_contours]; -- p.hole = 0; -- -- p.contour = new gpc_vertex_list[p.num_contours]; -- -- int i; -- //int* ph = p.hole; -- gpc_vertex_list* pv = p.contour; -- for(i = 0; i < p.num_contours; i++) -- { -- const contour_header_type& h = m_contour_accumulator[i]; -- // *ph++ = h.hole_flag; -- pv->num_vertices = h.num_vertices; -- pv->vertex = h.vertices; -- ++pv; -- } -- } -- } -- -- -- //------------------------------------------------------------------------ -- template -- void conv_gpc::start_extracting() -- { -- m_status = status_move_to; -- m_contour = -1; -- m_vertex = -1; -- } -- -- -- //------------------------------------------------------------------------ -- template -- bool conv_gpc::next_contour() -- { -- if(++m_contour < m_result.num_contours) -- { -- m_vertex = -1; -- return true; -- } -- return false; -- } -- -- -- //------------------------------------------------------------------------ -- template -- inline bool conv_gpc::next_vertex(double* x, double* y) -- { -- const gpc_vertex_list& vlist = m_result.contour[m_contour]; -- if(++m_vertex < vlist.num_vertices) -- { -- const gpc_vertex& v = vlist.vertex[m_vertex]; -- *x = v.x; -- *y = v.y; -- return true; -- } -- return false; -- } -- -- -- //------------------------------------------------------------------------ -- template -- void conv_gpc::rewind(unsigned path_id) -- { -- free_result(); -- m_src_a->rewind(path_id); -- m_src_b->rewind(path_id); -- add(*m_src_a, m_poly_a); -- add(*m_src_b, m_poly_b); -- switch(m_operation) -- { -- case gpc_or: -- gpc_polygon_clip(GPC_UNION, -- &m_poly_a, -- &m_poly_b, -- &m_result); -- break; -- -- case gpc_and: -- gpc_polygon_clip(GPC_INT, -- &m_poly_a, -- &m_poly_b, -- &m_result); -- break; -- -- case gpc_xor: -- gpc_polygon_clip(GPC_XOR, -- &m_poly_a, -- &m_poly_b, -- &m_result); -- break; -- -- case gpc_a_minus_b: -- gpc_polygon_clip(GPC_DIFF, -- &m_poly_a, -- &m_poly_b, -- &m_result); -- break; -- -- case gpc_b_minus_a: -- gpc_polygon_clip(GPC_DIFF, -- &m_poly_b, -- &m_poly_a, -- &m_result); -- break; -- } -- start_extracting(); -- } -- -- -- //------------------------------------------------------------------------ -- template -- unsigned conv_gpc::vertex(double* x, double* y) -- { -- if(m_status == status_move_to) -- { -- if(next_contour()) -- { -- if(next_vertex(x, y)) -- { -- m_status = status_line_to; -- return path_cmd_move_to; -- } -- m_status = status_stop; -- return path_cmd_end_poly | path_flags_close; -- } -- } -- else -- { -- if(next_vertex(x, y)) -- { -- return path_cmd_line_to; -- } -- else -- { -- m_status = status_move_to; -- } -- return path_cmd_end_poly | path_flags_close; -- } -- return path_cmd_stop; -- } -- -- --} -- -- --#endif -diff --git a/src/third_party/agg/include/agg_conv_transform.h b/src/third_party/agg/include/agg_conv_transform.h -index 1203e6c..1710877 100644 ---- a/src/third_party/agg/include/agg_conv_transform.h -+++ b/src/third_party/agg/include/agg_conv_transform.h -@@ -31,8 +31,7 @@ namespace agg - public: - conv_transform(VertexSource& source, const Transformer& tr) : - m_source(&source), m_trans(&tr) {} -- -- void set_source(VertexSource& source) { m_source = &source; } -+ void attach(VertexSource& source) { m_source = &source; } - - void rewind(unsigned path_id) - { -diff --git a/src/third_party/agg/include/agg_conv_unclose_polygon.h b/src/third_party/agg/include/agg_conv_unclose_polygon.h -index 5474ce2..66ea458 100644 ---- a/src/third_party/agg/include/agg_conv_unclose_polygon.h -+++ b/src/third_party/agg/include/agg_conv_unclose_polygon.h -@@ -25,8 +25,7 @@ namespace agg - { - public: - conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {} -- -- void set_source(VertexSource& source) { m_source = &source; } -+ void attach(VertexSource& source) { m_source = &source; } - - void rewind(unsigned path_id) - { -diff --git a/src/third_party/agg/include/agg_curves.h b/src/third_party/agg/include/agg_curves.h -index 1cb69c3..1ef02e8 100644 ---- a/src/third_party/agg/include/agg_curves.h -+++ b/src/third_party/agg/include/agg_curves.h -@@ -152,7 +152,6 @@ namespace agg - - double m_approximation_scale; - double m_distance_tolerance_square; -- double m_distance_tolerance_manhattan; - double m_angle_tolerance; - unsigned m_count; - pod_bvector m_points; -@@ -464,7 +463,6 @@ namespace agg - - double m_approximation_scale; - double m_distance_tolerance_square; -- double m_distance_tolerance_manhattan; - double m_angle_tolerance; - double m_cusp_limit; - unsigned m_count; -diff --git a/src/third_party/agg/include/agg_font_cache_manager.h b/src/third_party/agg/include/agg_font_cache_manager.h -index 4585465..e9cf5bf 100644 ---- a/src/third_party/agg/include/agg_font_cache_manager.h -+++ b/src/third_party/agg/include/agg_font_cache_manager.h -@@ -52,9 +52,13 @@ namespace agg - enum block_size_e { block_size = 16384-16 }; - - //-------------------------------------------------------------------- -- font_cache(const char* font_signature) : -+ font_cache() : - m_allocator(block_size), - m_font_signature(0) -+ {} -+ -+ //-------------------------------------------------------------------- -+ void signature(const char* font_signature) - { - m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1); - strcpy(m_font_signature, font_signature); -@@ -103,18 +107,18 @@ namespace agg - (glyph_cache*)m_allocator.allocate(sizeof(glyph_cache), - sizeof(double)); - -- glyph->glyph_index = glyph_index; -- glyph->data = m_allocator.allocate(data_size); -- glyph->data_size = data_size; -- glyph->data_type = data_type; -- glyph->bounds = bounds; -- glyph->advance_x = advance_x; -- glyph->advance_y = advance_y; -+ glyph->glyph_index = glyph_index; -+ glyph->data = m_allocator.allocate(data_size); -+ glyph->data_size = data_size; -+ glyph->data_type = data_type; -+ glyph->bounds = bounds; -+ glyph->advance_x = advance_x; -+ glyph->advance_y = advance_y; - return m_glyphs[msb][lsb] = glyph; - } - - private: -- pod_allocator m_allocator; -+ block_allocator m_allocator; - glyph_cache** m_glyphs[256]; - char* m_font_signature; - }; -@@ -135,14 +139,14 @@ namespace agg - unsigned i; - for(i = 0; i < m_num_fonts; ++i) - { -- delete m_fonts[i]; -+ obj_allocator::deallocate(m_fonts[i]); - } -- delete [] m_fonts; -+ pod_allocator::deallocate(m_fonts, m_max_fonts); - } - - //-------------------------------------------------------------------- - font_cache_pool(unsigned max_fonts=32) : -- m_fonts(new font_cache* [max_fonts]), -+ m_fonts(pod_allocator::allocate(max_fonts)), - m_max_fonts(max_fonts), - m_num_fonts(0), - m_cur_font(0) -@@ -157,8 +161,9 @@ namespace agg - { - if(reset_cache) - { -- delete m_fonts[idx]; -- m_fonts[idx] = new font_cache(font_signature); -+ obj_allocator::deallocate(m_fonts[idx]); -+ m_fonts[idx] = obj_allocator::allocate(); -+ m_fonts[idx]->signature(font_signature); - } - m_cur_font = m_fonts[idx]; - } -@@ -166,13 +171,14 @@ namespace agg - { - if(m_num_fonts >= m_max_fonts) - { -- delete m_fonts[0]; -+ obj_allocator::deallocate(m_fonts[0]); - memcpy(m_fonts, - m_fonts + 1, - (m_max_fonts - 1) * sizeof(font_cache*)); - m_num_fonts = m_max_fonts - 1; - } -- m_fonts[m_num_fonts] = new font_cache(font_signature); -+ m_fonts[m_num_fonts] = obj_allocator::allocate(); -+ m_fonts[m_num_fonts]->signature(font_signature); - m_cur_font = m_fonts[m_num_fonts]; - ++m_num_fonts; - } -@@ -361,6 +367,12 @@ namespace agg - m_prev_glyph = m_last_glyph = 0; - } - -+ //-------------------------------------------------------------------- -+ void reset() -+ { -+ m_prev_glyph = m_last_glyph = 0; -+ } -+ - private: - //-------------------------------------------------------------------- - font_cache_manager(const self_type&); -diff --git a/src/third_party/agg/include/agg_gamma_lut.h b/src/third_party/agg/include/agg_gamma_lut.h -index cef8788..c3e8dfc 100644 ---- a/src/third_party/agg/include/agg_gamma_lut.h -+++ b/src/third_party/agg/include/agg_gamma_lut.h -@@ -45,14 +45,14 @@ namespace agg - - ~gamma_lut() - { -- delete [] m_inv_gamma; -- delete [] m_dir_gamma; -+ pod_allocator::deallocate(m_inv_gamma, hi_res_size); -+ pod_allocator::deallocate(m_dir_gamma, gamma_size); - } - - gamma_lut() : - m_gamma(1.0), -- m_dir_gamma(new HiResT[gamma_size]), -- m_inv_gamma(new LoResT[hi_res_size]) -+ m_dir_gamma(pod_allocator::allocate(gamma_size)), -+ m_inv_gamma(pod_allocator::allocate(hi_res_size)) - { - unsigned i; - for(i = 0; i < gamma_size; i++) -@@ -68,8 +68,8 @@ namespace agg - - gamma_lut(double g) : - m_gamma(1.0), -- m_dir_gamma(new HiResT[gamma_size]), -- m_inv_gamma(new LoResT[hi_res_size]) -+ m_dir_gamma(pod_allocator::allocate(gamma_size)), -+ m_inv_gamma(pod_allocator::allocate(hi_res_size)) - { - gamma(g); - } -diff --git a/src/third_party/agg/include/agg_gsv_text.h b/src/third_party/agg/include/agg_gsv_text.h -index cbfdc11..269c8a4 100644 ---- a/src/third_party/agg/include/agg_gsv_text.h -+++ b/src/third_party/agg/include/agg_gsv_text.h -@@ -20,7 +20,7 @@ - #ifndef AGG_GSV_TEXT_INCLUDED - #define AGG_GSV_TEXT_INCLUDED - --#include "agg_basics.h" -+#include "agg_array.h" - #include "agg_conv_stroke.h" - #include "agg_conv_transform.h" - -@@ -43,7 +43,6 @@ namespace agg - }; - - public: -- ~gsv_text(); - gsv_text(); - - void font(const void* font); -@@ -80,30 +79,28 @@ namespace agg - } - - private: -- double m_x; -- double m_y; -- double m_start_x; -- double m_width; -- double m_height; -- double m_space; -- double m_line_space; -- char m_chr[2]; -- char* m_text; -- char* m_text_buf; -- unsigned m_buf_size; -- char* m_cur_chr; -- const void* m_font; -- char* m_loaded_font; -- status m_status; -- bool m_big_endian; -- bool m_flip; -- -- int8u* m_indices; -- int8* m_glyphs; -- int8* m_bglyph; -- int8* m_eglyph; -- double m_w; -- double m_h; -+ double m_x; -+ double m_y; -+ double m_start_x; -+ double m_width; -+ double m_height; -+ double m_space; -+ double m_line_space; -+ char m_chr[2]; -+ char* m_text; -+ pod_array m_text_buf; -+ char* m_cur_chr; -+ const void* m_font; -+ pod_array m_loaded_font; -+ status m_status; -+ bool m_big_endian; -+ bool m_flip; -+ int8u* m_indices; -+ int8* m_glyphs; -+ int8* m_bglyph; -+ int8* m_eglyph; -+ double m_w; -+ double m_h; - }; - - -diff --git a/src/third_party/agg/include/agg_image_accessors.h b/src/third_party/agg/include/agg_image_accessors.h -index fe5b7f4..d551dbc 100644 ---- a/src/third_party/agg/include/agg_image_accessors.h -+++ b/src/third_party/agg/include/agg_image_accessors.h -@@ -38,7 +38,7 @@ namespace agg - pixfmt_type::make_pix(m_bk_buf, bk); - } - -- void set_source(const pixfmt_type& pixf) -+ void attach(const pixfmt_type& pixf) - { - m_pixf = &pixf; - } -@@ -116,7 +116,7 @@ namespace agg - image_accessor_no_clip() {} - image_accessor_no_clip(const pixfmt_type& pixf) : m_pixf(&pixf) {} - -- void set_source(const pixfmt_type& pixf) -+ void attach(const pixfmt_type& pixf) - { - m_pixf = &pixf; - } -@@ -161,7 +161,7 @@ namespace agg - image_accessor_clone() {} - image_accessor_clone(const pixfmt_type& pixf) : m_pixf(&pixf) {} - -- void set_source(const pixfmt_type& pixf) -+ void attach(const pixfmt_type& pixf) - { - m_pixf = &pixf; - } -@@ -184,7 +184,7 @@ namespace agg - m_x = m_x0 = x; - m_y = y; - if(y >= 0 && y < (int)m_pixf->height() && -- x >= 0 && x+len <= (int)m_pixf->width()) -+ x >= 0 && (int)(x+len) <= (int)m_pixf->width()) - { - return m_pix_ptr = m_pixf->pix_ptr(x, y); - } -@@ -239,7 +239,7 @@ namespace agg - m_wrap_y(pixf.height()) - {} - -- void set_source(const pixfmt_type& pixf) -+ void attach(const pixfmt_type& pixf) - { - m_pixf = &pixf; - } -diff --git a/src/third_party/agg/include/agg_image_filters.h b/src/third_party/agg/include/agg_image_filters.h -index 2738cad..8e1bc8f 100644 ---- a/src/third_party/agg/include/agg_image_filters.h -+++ b/src/third_party/agg/include/agg_image_filters.h -@@ -20,6 +20,7 @@ - #ifndef AGG_IMAGE_FILTERS_INCLUDED - #define AGG_IMAGE_FILTERS_INCLUDED - -+#include "agg_array.h" - #include "agg_math.h" - - namespace agg -@@ -46,9 +47,6 @@ namespace agg - class image_filter_lut - { - public: -- ~image_filter_lut(); -- image_filter_lut(); -- - template void calculate(const FilterF& filter, - bool normalization=true) - { -@@ -71,18 +69,18 @@ namespace agg - } - } - -+ image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {} -+ - template image_filter_lut(const FilterF& filter, -- bool normalization=true) : -- m_weight_array(0), -- m_max_size(0) -+ bool normalization=true) - { - calculate(filter, normalization); - } - -- double radius() const { return m_radius; } -- unsigned diameter() const { return m_diameter; } -- int start() const { return m_start; } -- const int16* weight_array() const { return m_weight_array; } -+ double radius() const { return m_radius; } -+ unsigned diameter() const { return m_diameter; } -+ int start() const { return m_start; } -+ const int16* weight_array() const { return &m_weight_array[0]; } - void normalize(); - - private: -@@ -90,11 +88,10 @@ namespace agg - image_filter_lut(const image_filter_lut&); - const image_filter_lut& operator = (const image_filter_lut&); - -- double m_radius; -- unsigned m_diameter; -- int m_start; -- int16* m_weight_array; -- unsigned m_max_size; -+ double m_radius; -+ unsigned m_diameter; -+ int m_start; -+ pod_array m_weight_array; - }; - - -diff --git a/src/third_party/agg/include/agg_line_aa_basics.h b/src/third_party/agg/include/agg_line_aa_basics.h -index 1fafb98..c5acb18 100644 ---- a/src/third_party/agg/include/agg_line_aa_basics.h -+++ b/src/third_party/agg/include/agg_line_aa_basics.h -@@ -142,8 +142,8 @@ namespace agg - int octant; - - //--------------------------------------------------------------------- -- static int8u s_orthogonal_quadrant[8]; -- static int8u s_diagonal_quadrant[8]; -+ static const int8u s_orthogonal_quadrant[8]; -+ static const int8u s_diagonal_quadrant[8]; - }; - - -diff --git a/src/third_party/agg/include/agg_math.h b/src/third_party/agg/include/agg_math.h -index 3d6e22c..6d3ff11 100644 ---- a/src/third_party/agg/include/agg_math.h -+++ b/src/third_party/agg/include/agg_math.h -@@ -33,28 +33,26 @@ namespace agg - // See calc_intersection - const double intersection_epsilon = 1.0e-30; - -- //------------------------------------------------------calc_point_location -- AGG_INLINE double calc_point_location(double x1, double y1, -- double x2, double y2, -- double x, double y) -+ //------------------------------------------------------------cross_product -+ AGG_INLINE double cross_product(double x1, double y1, -+ double x2, double y2, -+ double x, double y) - { - return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1); - } - -- - //--------------------------------------------------------point_in_triangle - AGG_INLINE bool point_in_triangle(double x1, double y1, - double x2, double y2, - double x3, double y3, - double x, double y) - { -- bool cp1 = calc_point_location(x1, y1, x2, y2, x, y) < 0.0; -- bool cp2 = calc_point_location(x2, y2, x3, y3, x, y) < 0.0; -- bool cp3 = calc_point_location(x3, y3, x1, y1, x, y) < 0.0; -+ bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0; -+ bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0; -+ bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0; - return cp1 == cp2 && cp2 == cp3 && cp3 == cp1; - } - -- - //-----------------------------------------------------------calc_distance - AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2) - { -@@ -63,6 +61,13 @@ namespace agg - return sqrt(dx * dx + dy * dy); - } - -+ //--------------------------------------------------------calc_sq_distance -+ AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2) -+ { -+ double dx = x2-x1; -+ double dy = y2-y1; -+ return dx * dx + dy * dy; -+ } - - //------------------------------------------------calc_line_point_distance - AGG_INLINE double calc_line_point_distance(double x1, double y1, -@@ -79,6 +84,53 @@ namespace agg - return ((x - x2) * dy - (y - y2) * dx) / d; - } - -+ //-------------------------------------------------------calc_line_point_u -+ AGG_INLINE double calc_segment_point_u(double x1, double y1, -+ double x2, double y2, -+ double x, double y) -+ { -+ double dx = x2 - x1; -+ double dy = y2 - y1; -+ -+ if(dx == 0 && dy == 0) -+ { -+ return 0; -+ } -+ -+ double pdx = x - x1; -+ double pdy = y - y1; -+ -+ return (pdx * dx + pdy * dy) / (dx * dx + dy * dy); -+ } -+ -+ //---------------------------------------------calc_line_point_sq_distance -+ AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, -+ double x2, double y2, -+ double x, double y, -+ double u) -+ { -+ if(u <= 0) -+ { -+ return calc_sq_distance(x, y, x1, y1); -+ } -+ else -+ if(u >= 1) -+ { -+ return calc_sq_distance(x, y, x2, y2); -+ } -+ return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1)); -+ } -+ -+ //---------------------------------------------calc_line_point_sq_distance -+ AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, -+ double x2, double y2, -+ double x, double y) -+ { -+ return -+ calc_segment_point_sq_distance( -+ x1, y1, x2, y2, x, y, -+ calc_segment_point_u(x1, y1, x2, y2, x, y)); -+ } - - //-------------------------------------------------------calc_intersection - AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by, -@@ -94,7 +146,6 @@ namespace agg - return true; - } - -- - //-----------------------------------------------------intersection_exists - AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2, - double x3, double y3, double x4, double y4) -@@ -122,7 +173,6 @@ namespace agg - //return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0; - } - -- - //--------------------------------------------------------calc_orthogonal - AGG_INLINE void calc_orthogonal(double thickness, - double x1, double y1, -@@ -132,11 +182,10 @@ namespace agg - double dx = x2 - x1; - double dy = y2 - y1; - double d = sqrt(dx*dx + dy*dy); -- *x = thickness * dy / d; -- *y = thickness * dx / d; -+ *x = thickness * dy / d; -+ *y = -thickness * dx / d; - } - -- - //--------------------------------------------------------dilate_triangle - AGG_INLINE void dilate_triangle(double x1, double y1, - double x2, double y2, -@@ -150,10 +199,10 @@ namespace agg - double dy2=0.0; - double dx3=0.0; - double dy3=0.0; -- double loc = calc_point_location(x1, y1, x2, y2, x3, y3); -+ double loc = cross_product(x1, y1, x2, y2, x3, y3); - if(fabs(loc) > intersection_epsilon) - { -- if(calc_point_location(x1, y1, x2, y2, x3, y3) > 0.0) -+ if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0) - { - d = -d; - } -@@ -161,12 +210,12 @@ namespace agg - calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2); - calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3); - } -- *x++ = x1 + dx1; *y++ = y1 - dy1; -- *x++ = x2 + dx1; *y++ = y2 - dy1; -- *x++ = x2 + dx2; *y++ = y2 - dy2; -- *x++ = x3 + dx2; *y++ = y3 - dy2; -- *x++ = x3 + dx3; *y++ = y3 - dy3; -- *x++ = x1 + dx3; *y++ = y1 - dy3; -+ *x++ = x1 + dx1; *y++ = y1 + dy1; -+ *x++ = x2 + dx1; *y++ = y2 + dy1; -+ *x++ = x2 + dx2; *y++ = y2 + dy2; -+ *x++ = x3 + dx2; *y++ = y3 + dy2; -+ *x++ = x3 + dx3; *y++ = y3 + dy3; -+ *x++ = x1 + dx3; *y++ = y1 + dy3; - } - - //------------------------------------------------------calc_triangle_area -@@ -177,7 +226,6 @@ namespace agg - return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5; - } - -- - //-------------------------------------------------------calc_polygon_area - template double calc_polygon_area(const Storage& st) - { -diff --git a/src/third_party/agg/include/agg_math_stroke.h b/src/third_party/agg/include/agg_math_stroke.h -index 621f87a..c7f0dbd 100644 ---- a/src/third_party/agg/include/agg_math_stroke.h -+++ b/src/third_party/agg/include/agg_math_stroke.h -@@ -38,9 +38,9 @@ namespace agg - { - miter_join = 0, - miter_join_revert = 1, -- miter_join_round = 4, - round_join = 2, -- bevel_join = 3 -+ bevel_join = 3, -+ miter_join_round = 4 - }; - - -@@ -53,80 +53,162 @@ namespace agg - inner_round - }; - -- // Minimal angle to calculate round joins, less than 0.1 degree. -- const double stroke_theta = 0.001; //----stroke_theta -- -- //--------------------------------------------------------stroke_calc_arc -- template -- void stroke_calc_arc(VertexConsumer& out_vertices, -- double x, double y, -- double dx1, double dy1, -- double dx2, double dy2, -- double width, -- double approximation_scale) -+ //------------------------------------------------------------math_stroke -+ template class math_stroke - { -+ public: - typedef typename VertexConsumer::value_type coord_type; - -- double a1 = atan2(dy1, dx1); -- double a2 = atan2(dy2, dx2); -- double da = a1 - a2; -+ math_stroke(); -+ -+ void line_cap(line_cap_e lc) { m_line_cap = lc; } -+ void line_join(line_join_e lj) { m_line_join = lj; } -+ void inner_join(inner_join_e ij) { m_inner_join = ij; } -+ -+ line_cap_e line_cap() const { return m_line_cap; } -+ line_join_e line_join() const { return m_line_join; } -+ inner_join_e inner_join() const { return m_inner_join; } -+ -+ void width(double w); -+ void miter_limit(double ml) { m_miter_limit = ml; } -+ void miter_limit_theta(double t); -+ void inner_miter_limit(double ml) { m_inner_miter_limit = ml; } -+ void approximation_scale(double as) { m_approx_scale = as; } -+ -+ double width() const { return m_width * 2.0; } -+ double miter_limit() const { return m_miter_limit; } -+ double inner_miter_limit() const { return m_inner_miter_limit; } -+ double approximation_scale() const { return m_approx_scale; } -+ -+ void calc_cap(VertexConsumer& out_vertices, -+ const vertex_dist& v0, -+ const vertex_dist& v1, -+ double len); -+ -+ void calc_join(VertexConsumer& out_vertices, -+ const vertex_dist& v0, -+ const vertex_dist& v1, -+ const vertex_dist& v2, -+ double len1, -+ double len2); -+ -+ private: -+ void calc_arc(VertexConsumer& out_vertices, -+ double x, double y, -+ double dx1, double dy1, -+ double dx2, double dy2); -+ -+ void calc_miter(VertexConsumer& out_vertices, -+ const vertex_dist& v0, -+ const vertex_dist& v1, -+ const vertex_dist& v2, -+ double dx1, double dy1, -+ double dx2, double dy2, -+ line_join_e lj, -+ double ml); -+ -+ double m_width; -+ double m_width_abs; -+ int m_width_sign; -+ double m_miter_limit; -+ double m_inner_miter_limit; -+ double m_approx_scale; -+ line_cap_e m_line_cap; -+ line_join_e m_line_join; -+ inner_join_e m_inner_join; -+ }; -+ -+ //----------------------------------------------------------------------- -+ template math_stroke::math_stroke() : -+ m_width(0.5), -+ m_width_abs(0.5), -+ m_width_sign(1), -+ m_miter_limit(4.0), -+ m_inner_miter_limit(1.01), -+ m_approx_scale(1.0), -+ m_line_cap(butt_cap), -+ m_line_join(miter_join), -+ m_inner_join(inner_miter) -+ { -+ } -+ -+ //----------------------------------------------------------------------- -+ template void math_stroke::width(double w) -+ { -+ m_width = w * 0.5; -+ if(m_width < 0) -+ { -+ m_width_abs = -m_width; -+ m_width_sign = -1; -+ } -+ else -+ { -+ m_width_abs = m_width; -+ m_width_sign = 1; -+ } -+ } - -- // Possible optimization. Not important at all; consumes time but happens rarely -- //if(fabs(da) < stroke_theta) -- //{ -- // out_vertices.add(coord_type((x + x + dx1 + dx2) * 0.5, -- // (y + y + dy1 + dy2) * 0.5)); -- // return; -- //} -+ //----------------------------------------------------------------------- -+ template void math_stroke::miter_limit_theta(double t) -+ { -+ m_miter_limit = 1.0 / sin(t * 0.5) ; -+ } - -- bool ccw = da > 0.0 && da < pi; -+ //----------------------------------------------------------------------- -+ template -+ void math_stroke::calc_arc(VC& out_vertices, -+ double x, double y, -+ double dx1, double dy1, -+ double dx2, double dy2) -+ { -+ double a1 = atan2(dy1 * m_width_sign, dx1 * m_width_sign); -+ double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign); -+ double da = a1 - a2; -+ int i, n; - -- if(width < 0) width = -width; -- da = acos(width / (width + 0.125 / approximation_scale)) * 2; -+ da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2; - - out_vertices.add(coord_type(x + dx1, y + dy1)); -- if(!ccw) -+ if(m_width_sign > 0) - { - if(a1 > a2) a2 += 2 * pi; -- a2 -= da / 4; -+ n = int((a2 - a1) / da); -+ da = (a2 - a1) / (n + 1); - a1 += da; -- while(a1 < a2) -+ for(i = 0; i < n; i++) - { -- out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width)); -+ out_vertices.add(coord_type(x + cos(a1) * m_width, -+ y + sin(a1) * m_width)); - a1 += da; - } - } - else - { - if(a1 < a2) a2 -= 2 * pi; -- a2 += da / 4; -+ n = int((a1 - a2) / da); -+ da = (a1 - a2) / (n + 1); - a1 -= da; -- while(a1 > a2) -+ for(i = 0; i < n; i++) - { -- out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width)); -+ out_vertices.add(coord_type(x + cos(a1) * m_width, -+ y + sin(a1) * m_width)); - a1 -= da; - } - } - out_vertices.add(coord_type(x + dx2, y + dy2)); - } - -- -- -- //-------------------------------------------------------stroke_calc_miter -- template -- void stroke_calc_miter(VertexConsumer& out_vertices, -- const vertex_dist& v0, -- const vertex_dist& v1, -- const vertex_dist& v2, -- double dx1, double dy1, -- double dx2, double dy2, -- double width, -- line_join_e line_join, -- double miter_limit, -- double approximation_scale) -+ //----------------------------------------------------------------------- -+ template -+ void math_stroke::calc_miter(VC& out_vertices, -+ const vertex_dist& v0, -+ const vertex_dist& v1, -+ const vertex_dist& v2, -+ double dx1, double dy1, -+ double dx2, double dy2, -+ line_join_e lj, -+ double ml) - { -- typedef typename VertexConsumer::value_type coord_type; -- - double xi = v1.x; - double yi = v1.y; - bool miter_limit_exceeded = true; // Assume the worst -@@ -140,7 +222,7 @@ namespace agg - // Calculation of the intersection succeeded - //--------------------- - double d1 = calc_distance(v1.x, v1.y, xi, yi); -- double lim = width * miter_limit; -+ double lim = m_width_abs * ml; - if(d1 <= lim) - { - // Inside the miter limit -@@ -176,7 +258,7 @@ namespace agg - { - // Miter limit exceeded - //------------------------ -- switch(line_join) -+ switch(lj) - { - case miter_join_revert: - // For the compatibility with SVG, PDF, etc, -@@ -188,40 +270,29 @@ namespace agg - break; - - case miter_join_round: -- stroke_calc_arc(out_vertices, -- v1.x, v1.y, dx1, -dy1, dx2, -dy2, -- width, approximation_scale); -+ calc_arc(out_vertices, v1.x, v1.y, dx1, -dy1, dx2, -dy2); - break; - - default: - // If no miter-revert, calculate new dx1, dy1, dx2, dy2 - //---------------- -- out_vertices.add(coord_type(v1.x + dx1 + dy1 * miter_limit, -- v1.y - dy1 + dx1 * miter_limit)); -- out_vertices.add(coord_type(v1.x + dx2 - dy2 * miter_limit, -- v1.y - dy2 - dx2 * miter_limit)); -+ ml *= m_width_sign; -+ out_vertices.add(coord_type(v1.x + dx1 + dy1 * ml, -+ v1.y - dy1 + dx1 * ml)); -+ out_vertices.add(coord_type(v1.x + dx2 - dy2 * ml, -+ v1.y - dy2 - dx2 * ml)); - break; - } - } - } - -- -- -- -- -- - //--------------------------------------------------------stroke_calc_cap -- template -- void stroke_calc_cap(VertexConsumer& out_vertices, -- const vertex_dist& v0, -- const vertex_dist& v1, -- double len, -- line_cap_e line_cap, -- double width, -- double approximation_scale) -+ template -+ void math_stroke::calc_cap(VC& out_vertices, -+ const vertex_dist& v0, -+ const vertex_dist& v1, -+ double len) - { -- typedef typename VertexConsumer::value_type coord_type; -- - out_vertices.remove_all(); - - double dx1 = (v1.y - v0.y) / len; -@@ -229,71 +300,86 @@ namespace agg - double dx2 = 0; - double dy2 = 0; - -- dx1 *= width; -- dy1 *= width; -+ dx1 *= m_width; -+ dy1 *= m_width; - -- if(line_cap != round_cap) -+ if(m_line_cap != round_cap) - { -- if(line_cap == square_cap) -+ if(m_line_cap == square_cap) - { -- dx2 = dy1; -- dy2 = dx1; -+ dx2 = dy1 * m_width_sign; -+ dy2 = dx1 * m_width_sign; - } - out_vertices.add(coord_type(v0.x - dx1 - dx2, v0.y + dy1 - dy2)); - out_vertices.add(coord_type(v0.x + dx1 - dx2, v0.y - dy1 - dy2)); - } - else - { -- double a1 = atan2(dy1, -dx1); -- double a2 = a1 + pi; -- double da = acos(width / (width + 0.125 / approximation_scale)) * 2; -+ double da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2; -+ double a1; -+ int i; -+ int n = int(pi / da); -+ -+ da = pi / (n + 1); - out_vertices.add(coord_type(v0.x - dx1, v0.y + dy1)); -- a1 += da; -- a2 -= da/4; -- while(a1 < a2) -+ if(m_width_sign > 0) - { -- out_vertices.add(coord_type(v0.x + cos(a1) * width, -- v0.y + sin(a1) * width)); -+ a1 = atan2(dy1, -dx1); - a1 += da; -+ for(i = 0; i < n; i++) -+ { -+ out_vertices.add(coord_type(v0.x + cos(a1) * m_width, -+ v0.y + sin(a1) * m_width)); -+ a1 += da; -+ } -+ } -+ else -+ { -+ a1 = atan2(-dy1, dx1); -+ a1 -= da; -+ for(i = 0; i < n; i++) -+ { -+ out_vertices.add(coord_type(v0.x + cos(a1) * m_width, -+ v0.y + sin(a1) * m_width)); -+ a1 -= da; -+ } - } - out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1)); - } - } - -- -- -- //-------------------------------------------------------stroke_calc_join -- template -- void stroke_calc_join(VertexConsumer& out_vertices, -- const vertex_dist& v0, -- const vertex_dist& v1, -- const vertex_dist& v2, -- double len1, -- double len2, -- double width, -- line_join_e line_join, -- inner_join_e inner_join, -- double miter_limit, -- double inner_miter_limit, -- double approximation_scale) -+ //----------------------------------------------------------------------- -+ template -+ void math_stroke::calc_join(VC& out_vertices, -+ const vertex_dist& v0, -+ const vertex_dist& v1, -+ const vertex_dist& v2, -+ double len1, -+ double len2) - { -- typedef typename VertexConsumer::value_type coord_type; -- - double dx1, dy1, dx2, dy2; -+ double d; - -- dx1 = width * (v1.y - v0.y) / len1; -- dy1 = width * (v1.x - v0.x) / len1; -+ dx1 = m_width * (v1.y - v0.y) / len1; -+ dy1 = m_width * (v1.x - v0.x) / len1; - -- dx2 = width * (v2.y - v1.y) / len2; -- dy2 = width * (v2.x - v1.x) / len2; -+ dx2 = m_width * (v2.y - v1.y) / len2; -+ dy2 = m_width * (v2.x - v1.x) / len2; - - out_vertices.remove_all(); - -- if(calc_point_location(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y) > 0) -+ double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y); -+ if(cp != 0 && (cp > 0) == (m_width > 0)) - { - // Inner join - //--------------- -- switch(inner_join) -+ double limit = ((len1 < len2) ? len1 : len2) / m_width_abs; -+ if(limit < m_inner_miter_limit) -+ { -+ limit = m_inner_miter_limit; -+ } -+ -+ switch(m_inner_join) - { - default: // inner_bevel - out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); -@@ -301,30 +387,26 @@ namespace agg - break; - - case inner_miter: -- stroke_calc_miter(out_vertices, -- v0, v1, v2, dx1, dy1, dx2, dy2, -- width, -- miter_join_revert, -- inner_miter_limit, -- 1.0); -+ calc_miter(out_vertices, -+ v0, v1, v2, dx1, dy1, dx2, dy2, -+ miter_join_revert, -+ limit); - break; - - case inner_jag: - case inner_round: - { -- double d = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2); -+ 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.0); -+ calc_miter(out_vertices, -+ v0, v1, v2, dx1, dy1, dx2, dy2, -+ miter_join_revert, -+ limit); - } - else - { -- if(inner_join == inner_jag) -+ if(m_inner_join == inner_jag) - { - out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); - out_vertices.add(coord_type(v1.x, v1.y )); -@@ -334,9 +416,7 @@ namespace agg - { - 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); -+ calc_arc(out_vertices, v1.x, v1.y, dx2, -dy2, dx1, -dy1); - out_vertices.add(coord_type(v1.x, v1.y )); - out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); - } -@@ -349,23 +429,48 @@ namespace agg - { - // Outer join - //--------------- -- switch(line_join) -+ line_join_e lj = m_line_join; -+ if(m_line_join == round_join || m_line_join == bevel_join) -+ { -+ // This is an optimization that reduces the number of points -+ // in cases of almost collonear segments. If there's no -+ // visible difference between bevel and miter joins we'd rather -+ // use miter join because it adds only one point instead of two. -+ // -+ // Here we calculate the middle point between the bevel points -+ // and then, the distance between v1 and this middle point. -+ // At outer joins this distance always less than stroke width, -+ // because it's actually the height of an isosceles triangle of -+ // v1 and its two bevel points. If the difference between this -+ // width and this value is small (no visible bevel) we can switch -+ // to the miter join. -+ // -+ // The constant in the expression makes the result approximately -+ // the same as in round joins and caps. One can safely comment -+ // out this "if". -+ //------------------- -+ double dx = (dx1 + dx2) / 2; -+ double dy = (dy1 + dy2) / 2; -+ d = m_width_abs - sqrt(dx * dx + dy * dy); -+ if(d < 0.0625 / m_approx_scale) -+ { -+ lj = miter_join; -+ } -+ } -+ -+ switch(lj) - { - case miter_join: - 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); -+ calc_miter(out_vertices, -+ v0, v1, v2, dx1, dy1, dx2, dy2, -+ lj, -+ m_miter_limit); - break; - - case round_join: -- stroke_calc_arc(out_vertices, -- v1.x, v1.y, dx1, -dy1, dx2, -dy2, -- width, approximation_scale); -+ calc_arc(out_vertices, v1.x, v1.y, dx1, -dy1, dx2, -dy2); - break; - - default: // Bevel join -diff --git a/src/third_party/agg/include/agg_path_storage.h b/src/third_party/agg/include/agg_path_storage.h -index 6a001af..141d704 100644 ---- a/src/third_party/agg/include/agg_path_storage.h -+++ b/src/third_party/agg/include/agg_path_storage.h -@@ -90,10 +90,13 @@ namespace agg - T** coord_blk = m_coord_blocks + m_total_blocks - 1; - while(m_total_blocks--) - { -- delete [] *coord_blk; -+ pod_allocator::deallocate( -+ *coord_blk, -+ block_size * 2 + -+ block_size / (sizeof(T) / sizeof(unsigned char))); - --coord_blk; - } -- delete [] m_coord_blocks; -+ pod_allocator::deallocate(m_coord_blocks, m_max_blocks * 2); - m_total_blocks = 0; - m_max_blocks = 0; - m_coord_blocks = 0; -@@ -145,7 +148,7 @@ namespace agg - unsigned cmd = v.vertex(i, &x, &y); - add_vertex(x, y, cmd); - } -- return *this; -+ return *this; - } - - //------------------------------------------------------------------------ -@@ -298,7 +301,7 @@ namespace agg - if(nb >= m_max_blocks) - { - T** new_coords = -- new T* [(m_max_blocks + block_pool) * 2]; -+ pod_allocator::allocate((m_max_blocks + block_pool) * 2); - - unsigned char** new_cmds = - (unsigned char**)(new_coords + m_max_blocks + block_pool); -@@ -313,15 +316,15 @@ namespace agg - m_cmd_blocks, - m_max_blocks * sizeof(unsigned char*)); - -- delete [] m_coord_blocks; -+ pod_allocator::deallocate(m_coord_blocks, m_max_blocks * 2); - } - m_coord_blocks = new_coords; -- m_cmd_blocks = new_cmds; -- m_max_blocks += block_pool; -+ m_cmd_blocks = new_cmds; -+ m_max_blocks += block_pool; - } - m_coord_blocks[nb] = -- new T [block_size * 2 + -- block_size / (sizeof(T) / sizeof(unsigned char))]; -+ pod_allocator::allocate(block_size * 2 + -+ block_size / (sizeof(T) / sizeof(unsigned char))); - - m_cmd_blocks[nb] = - (unsigned char*)(m_coord_blocks[nb] + block_size * 2); -@@ -1232,10 +1235,7 @@ namespace agg - while(end < m_vertices.total_vertices() && - !is_next_poly(m_vertices.command(end))) ++end; - -- if(end - start > 2) -- { -- invert_polygon(start, end); -- } -+ invert_polygon(start, end); - } - - //------------------------------------------------------------------------ -diff --git a/src/third_party/agg/include/agg_pixfmt_amask_adaptor.h b/src/third_party/agg/include/agg_pixfmt_amask_adaptor.h -index 0c7b0e3..1f2c12e 100644 ---- a/src/third_party/agg/include/agg_pixfmt_amask_adaptor.h -+++ b/src/third_party/agg/include/agg_pixfmt_amask_adaptor.h -@@ -18,6 +18,7 @@ - - - #include -+#include "agg_array.h" - #include "agg_rendering_buffer.h" - - -@@ -38,38 +39,40 @@ namespace agg - - void realloc_span(unsigned len) - { -- if(len > m_max_len) -+ if(len > m_span.size()) - { -- delete [] m_span; -- m_span = new cover_type[m_max_len = len + span_extra_tail]; -+ m_span.resize(len + span_extra_tail); - } - } - - void init_span(unsigned len) - { - realloc_span(len); -- -- // ATTN! May work incorrectly if cover_type is more that one byte -- memset(m_span, amask_type::cover_full, len * sizeof(cover_type)); -+ memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type)); - } - - void init_span(unsigned len, const cover_type* covers) - { - realloc_span(len); -- memcpy(m_span, covers, len * sizeof(cover_type)); -+ memcpy(&m_span[0], covers, len * sizeof(cover_type)); - } - - - public: -- ~pixfmt_amask_adaptor() { delete [] m_span; } -- - pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& mask) : -- m_pixf(&pixf), m_mask(&mask), m_span(0), m_max_len(0) -+ m_pixf(&pixf), m_mask(&mask), m_span() - {} - - void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; } - void attach_alpha_mask(const amask_type& mask) { m_mask = &mask; } - -+ //-------------------------------------------------------------------- -+ template -+ bool attach_pixfmt(PixFmt_& pixf, int x1, int y1, int x2, int y2) -+ { -+ return m_pixf->attach(pixf, x1, y1, x2, y2); -+ } -+ - //-------------------------------------------------------------------- - unsigned width() const { return m_pixf->width(); } - unsigned height() const { return m_pixf->height(); } -@@ -98,8 +101,8 @@ namespace agg - const color_type& c) - { - realloc_span(len); -- m_mask->fill_hspan(x, y, m_span, len); -- m_pixf->blend_solid_hspan(x, y, len, c, m_span); -+ m_mask->fill_hspan(x, y, &m_span[0], len); -+ m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]); - } - - //-------------------------------------------------------------------- -@@ -109,8 +112,8 @@ namespace agg - cover_type cover) - { - init_span(len); -- m_mask->combine_hspan(x, y, m_span, len); -- m_pixf->blend_solid_hspan(x, y, len, c, m_span); -+ m_mask->combine_hspan(x, y, &m_span[0], len); -+ m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]); - } - - //-------------------------------------------------------------------- -@@ -119,8 +122,8 @@ namespace agg - const color_type& c) - { - realloc_span(len); -- m_mask->fill_vspan(x, y, m_span, len); -- m_pixf->blend_solid_vspan(x, y, len, c, m_span); -+ m_mask->fill_vspan(x, y, &m_span[0], len); -+ m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]); - } - - //-------------------------------------------------------------------- -@@ -130,8 +133,8 @@ namespace agg - cover_type cover) - { - init_span(len); -- m_mask->combine_vspan(x, y, m_span, len); -- m_pixf->blend_solid_vspan(x, y, len, c, m_span); -+ m_mask->combine_vspan(x, y, &m_span[0], len); -+ m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]); - } - - //-------------------------------------------------------------------- -@@ -151,8 +154,8 @@ namespace agg - const cover_type* covers) - { - init_span(len, covers); -- m_mask->combine_hspan(x, y, m_span, len); -- m_pixf->blend_solid_hspan(x, y, len, c, m_span); -+ m_mask->combine_hspan(x, y, &m_span[0], len); -+ m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]); - } - - -@@ -163,8 +166,8 @@ namespace agg - const cover_type* covers) - { - init_span(len, covers); -- m_mask->combine_vspan(x, y, m_span, len); -- m_pixf->blend_solid_vspan(x, y, len, c, m_span); -+ m_mask->combine_vspan(x, y, &m_span[0], len); -+ m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]); - } - - -@@ -172,10 +175,17 @@ namespace agg - void copy_color_hspan(int x, int y, unsigned len, const color_type* colors) - { - realloc_span(len); -- m_mask->fill_hspan(x, y, m_span, len); -- m_pixf->blend_color_hspan(x, y, len, colors, m_span, cover_full); -+ m_mask->fill_hspan(x, y, &m_span[0], len); -+ m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover_full); - } - -+ //-------------------------------------------------------------------- -+ void copy_color_vspan(int x, int y, unsigned len, const color_type* colors) -+ { -+ realloc_span(len); -+ m_mask->fill_vspan(x, y, &m_span[0], len); -+ m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover_full); -+ } - - //-------------------------------------------------------------------- - void blend_color_hspan(int x, int y, -@@ -187,14 +197,14 @@ namespace agg - if(covers) - { - init_span(len, covers); -- m_mask->combine_hspan(x, y, m_span, len); -+ m_mask->combine_hspan(x, y, &m_span[0], len); - } - else - { - realloc_span(len); -- m_mask->fill_hspan(x, y, m_span, len); -+ m_mask->fill_hspan(x, y, &m_span[0], len); - } -- m_pixf->blend_color_hspan(x, y, len, colors, m_span, cover); -+ m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover); - } - - -@@ -208,22 +218,20 @@ namespace agg - if(covers) - { - init_span(len, covers); -- m_mask->combine_vspan(x, y, m_span, len); -+ m_mask->combine_vspan(x, y, &m_span[0], len); - } - else - { - realloc_span(len); -- m_mask->fill_vspan(x, y, m_span, len); -+ m_mask->fill_vspan(x, y, &m_span[0], len); - } -- m_pixf->blend_color_vspan(x, y, len, colors, m_span, cover); -+ m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover); - } - - private: -- pixfmt_type* m_pixf; -- const amask_type* m_mask; -- -- cover_type* m_span; -- unsigned m_max_len; -+ pixfmt_type* m_pixf; -+ const amask_type* m_mask; -+ pod_array m_span; - }; - - } -diff --git a/src/third_party/agg/include/agg_pixfmt_gray.h b/src/third_party/agg/include/agg_pixfmt_gray.h -index 64fc9a9..08b3d7d 100644 ---- a/src/third_party/agg/include/agg_pixfmt_gray.h -+++ b/src/third_party/agg/include/agg_pixfmt_gray.h -@@ -128,7 +128,9 @@ namespace agg - base_shift = color_type::base_shift, - base_scale = color_type::base_scale, - base_mask = color_type::base_mask, -- pix_width = sizeof(value_type) -+ pix_width = sizeof(value_type), -+ pix_step = Step, -+ pix_offset = Offset - }; - - private: -@@ -174,27 +176,43 @@ namespace agg - pixfmt_alpha_blend_gray(rbuf_type& rb) : - m_rbuf(&rb) - {} -+ void attach(rbuf_type& rb) { m_rbuf = &rb; } -+ //-------------------------------------------------------------------- -+ -+ template -+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) -+ { -+ rect_i r(x1, y1, x2, y2); -+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) -+ { -+ int stride = pixf.stride(); -+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), -+ (r.x2 - r.x1) + 1, -+ (r.y2 - r.y1) + 1, -+ stride); -+ return true; -+ } -+ return false; -+ } - - //-------------------------------------------------------------------- - AGG_INLINE unsigned width() const { return m_rbuf->width(); } - AGG_INLINE unsigned height() const { return m_rbuf->height(); } -+ AGG_INLINE int stride() const { return m_rbuf->stride(); } - - //-------------------------------------------------------------------- -- const int8u* row_ptr(int y) const -- { -- return m_rbuf->row_ptr(y); -- } -+ int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } -+ const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } -+ row_data row(int y) const { return m_rbuf->row(y); } - -- //-------------------------------------------------------------------- - const int8u* pix_ptr(int x, int y) const - { -- return m_rbuf->row_ptr(y) + x * pix_width; -+ return m_rbuf->row_ptr(y) + x * Step + Offset; - } - -- //-------------------------------------------------------------------- -- row_data row(int x, int y) const -+ int8u* pix_ptr(int x, int y) - { -- return m_rbuf->row(y); -+ return m_rbuf->row_ptr(y) + x * Step + Offset; - } - - //-------------------------------------------------------------------- -@@ -206,7 +224,7 @@ namespace agg - //-------------------------------------------------------------------- - AGG_INLINE color_type pixel(int x, int y) const - { -- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset; -+ value_type* p = (value_type*)m_rbuf->row_ptr(y) + x * Step + Offset; - return color_type(*p); - } - -@@ -399,13 +417,29 @@ namespace agg - - do - { -- *p++ = colors->v; -+ *p = colors->v; -+ p += Step; - ++colors; - } - while(--len); - } - - -+ //-------------------------------------------------------------------- -+ void copy_color_vspan(int x, int y, -+ unsigned len, -+ const color_type* colors) -+ { -+ do -+ { -+ value_type* p = (value_type*) -+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset; -+ *p = colors->v; -+ ++colors; -+ } -+ while(--len); -+ } -+ - - //-------------------------------------------------------------------- - void blend_color_hspan(int x, int y, -diff --git a/src/third_party/agg/include/agg_pixfmt_rgb.h b/src/third_party/agg/include/agg_pixfmt_rgb.h -index 9a96851..51450cf 100644 ---- a/src/third_party/agg/include/agg_pixfmt_rgb.h -+++ b/src/third_party/agg/include/agg_pixfmt_rgb.h -@@ -173,8 +173,8 @@ namespace agg - { - public: - typedef RenBuf rbuf_type; -- typedef typename rbuf_type::row_data row_data; - typedef Blender blender_type; -+ typedef typename rbuf_type::row_data row_data; - typedef typename blender_type::color_type color_type; - typedef typename blender_type::order_type order_type; - typedef typename color_type::value_type value_type; -@@ -234,6 +234,24 @@ namespace agg - pixfmt_alpha_blend_rgb(rbuf_type& rb) : - m_rbuf(&rb) - {} -+ void attach(rbuf_type& rb) { m_rbuf = &rb; } -+ -+ //-------------------------------------------------------------------- -+ template -+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) -+ { -+ rect_i r(x1, y1, x2, y2); -+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) -+ { -+ int stride = pixf.stride(); -+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), -+ (r.x2 - r.x1) + 1, -+ (r.y2 - r.y1) + 1, -+ stride); -+ return true; -+ } -+ return false; -+ } - - //-------------------------------------------------------------------- - Blender& blender() { return m_blender; } -@@ -241,23 +259,22 @@ namespace agg - //-------------------------------------------------------------------- - AGG_INLINE unsigned width() const { return m_rbuf->width(); } - AGG_INLINE unsigned height() const { return m_rbuf->height(); } -+ AGG_INLINE int stride() const { return m_rbuf->stride(); } - - //-------------------------------------------------------------------- -- const int8u* row_ptr(int y) const -- { -- return m_rbuf->row_ptr(y); -- } -+ AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } -+ AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } -+ AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } - - //-------------------------------------------------------------------- -- const int8u* pix_ptr(int x, int y) const -- { -- return m_rbuf->row_ptr(y) + x * pix_width; -+ AGG_INLINE int8u* pix_ptr(int x, int y) -+ { -+ return m_rbuf->row_ptr(y) + x * pix_width; - } - -- //-------------------------------------------------------------------- -- row_data row(int x, int y) const -- { -- return m_rbuf->row(y); -+ AGG_INLINE const int8u* pix_ptr(int x, int y) const -+ { -+ return m_rbuf->row_ptr(y) + x * pix_width; - } - - //-------------------------------------------------------------------- -@@ -484,6 +501,24 @@ namespace agg - } - - -+ //-------------------------------------------------------------------- -+ void copy_color_vspan(int x, int y, -+ unsigned len, -+ const color_type* colors) -+ { -+ do -+ { -+ value_type* p = (value_type*) -+ m_rbuf->row_ptr(x, y++, 1) + x + x + x; -+ p[order_type::R] = colors->r; -+ p[order_type::G] = colors->g; -+ p[order_type::B] = colors->b; -+ ++colors; -+ } -+ while(--len); -+ } -+ -+ - //-------------------------------------------------------------------- - void blend_color_hspan(int x, int y, - unsigned len, -diff --git a/src/third_party/agg/include/agg_pixfmt_rgb_packed.h b/src/third_party/agg/include/agg_pixfmt_rgb_packed.h -index ec2fbd4..7868085 100644 ---- a/src/third_party/agg/include/agg_pixfmt_rgb_packed.h -+++ b/src/third_party/agg/include/agg_pixfmt_rgb_packed.h -@@ -829,28 +829,46 @@ namespace agg - public: - //-------------------------------------------------------------------- - pixfmt_alpha_blend_rgb_packed(rbuf_type& rb) : m_rbuf(&rb) {} -+ void attach(rbuf_type& rb) { m_rbuf = &rb; } -+ -+ //-------------------------------------------------------------------- -+ template -+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) -+ { -+ rect_i r(x1, y1, x2, y2); -+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) -+ { -+ int stride = pixf.stride(); -+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), -+ (r.x2 - r.x1) + 1, -+ (r.y2 - r.y1) + 1, -+ stride); -+ return true; -+ } -+ return false; -+ } -+ - Blender& blender() { return m_blender; } - - //-------------------------------------------------------------------- - AGG_INLINE unsigned width() const { return m_rbuf->width(); } - AGG_INLINE unsigned height() const { return m_rbuf->height(); } -+ AGG_INLINE int stride() const { return m_rbuf->stride(); } - - //-------------------------------------------------------------------- -- const int8u* row_ptr(int y) const -- { -- return m_rbuf->row_ptr(y); -- } -+ AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } -+ AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } -+ AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } - - //-------------------------------------------------------------------- -- const int8u* pix_ptr(int x, int y) const -+ AGG_INLINE int8u* pix_ptr(int x, int y) - { - return m_rbuf->row_ptr(y) + x * pix_width; - } - -- //-------------------------------------------------------------------- -- row_data row(int x, int y) const -+ AGG_INLINE const int8u* pix_ptr(int x, int y) const - { -- return m_rbuf->row(y); -+ return m_rbuf->row_ptr(y) + x * pix_width; - } - - //-------------------------------------------------------------------- -@@ -1012,6 +1030,20 @@ namespace agg - while(--len); - } - -+ //-------------------------------------------------------------------- -+ void copy_color_vspan(int x, int y, -+ unsigned len, -+ const color_type* colors) -+ { -+ do -+ { -+ pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x; -+ *p = m_blender.make_pix(colors->r, colors->g, colors->b); -+ ++colors; -+ } -+ while(--len); -+ } -+ - //-------------------------------------------------------------------- - void blend_color_hspan(int x, int y, - unsigned len, -diff --git a/src/third_party/agg/include/agg_pixfmt_rgba.h b/src/third_party/agg/include/agg_pixfmt_rgba.h -index ab454cd..20ec129 100644 ---- a/src/third_party/agg/include/agg_pixfmt_rgba.h -+++ b/src/third_party/agg/include/agg_pixfmt_rgba.h -@@ -614,12 +614,15 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type s1a = base_mask - sa; -- calc_type d1a = base_mask - p[Order::A]; -- p[Order::R] = (value_type)((p[Order::R] * s1a + sr * d1a + base_mask) >> base_shift); -- p[Order::G] = (value_type)((p[Order::G] * s1a + sg * d1a + base_mask) >> base_shift); -- p[Order::B] = (value_type)((p[Order::B] * s1a + sb * d1a + base_mask) >> base_shift); -- p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask/2) >> (base_shift - 1))); -+ if(sa) -+ { -+ calc_type s1a = base_mask - sa; -+ calc_type d1a = base_mask - p[Order::A]; -+ p[Order::R] = (value_type)((p[Order::R] * s1a + sr * d1a + base_mask) >> base_shift); -+ p[Order::G] = (value_type)((p[Order::G] * s1a + sg * d1a + base_mask) >> base_shift); -+ p[Order::B] = (value_type)((p[Order::B] * s1a + sb * d1a + base_mask) >> base_shift); -+ p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask/2) >> (base_shift - 1))); -+ } - } - }; - -@@ -649,14 +652,17 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type dr = p[Order::R] + sr; -- calc_type dg = p[Order::G] + sg; -- calc_type db = p[Order::B] + sb; -- calc_type da = p[Order::A] + sa; -- p[Order::R] = (dr > base_mask) ? base_mask : dr; -- p[Order::G] = (dg > base_mask) ? base_mask : dg; -- p[Order::B] = (db > base_mask) ? base_mask : db; -- p[Order::A] = (da > base_mask) ? base_mask : da; -+ if(sa) -+ { -+ calc_type dr = p[Order::R] + sr; -+ calc_type dg = p[Order::G] + sg; -+ calc_type db = p[Order::B] + sb; -+ calc_type da = p[Order::A] + sa; -+ p[Order::R] = (dr > base_mask) ? base_mask : dr; -+ p[Order::G] = (dg > base_mask) ? base_mask : dg; -+ p[Order::B] = (db > base_mask) ? base_mask : db; -+ p[Order::A] = (da > base_mask) ? base_mask : da; -+ } - } - }; - -@@ -686,13 +692,17 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type dr = p[Order::R] - sr; -- calc_type dg = p[Order::G] - sg; -- calc_type db = p[Order::B] - sb; -- p[Order::R] = (dr > base_mask) ? 0 : dr; -- p[Order::G] = (dg > base_mask) ? 0 : dg; -- p[Order::B] = (db > base_mask) ? 0 : db; -- p[Order::A] = (value_type)(base_mask - (((base_mask - sa) * (base_mask - p[Order::A]) + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type dr = p[Order::R] - sr; -+ calc_type dg = p[Order::G] - sg; -+ calc_type db = p[Order::B] - sb; -+ p[Order::R] = (dr > base_mask) ? 0 : dr; -+ p[Order::G] = (dg > base_mask) ? 0 : dg; -+ p[Order::B] = (db > base_mask) ? 0 : db; -+ p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); -+ //p[Order::A] = (value_type)(base_mask - (((base_mask - sa) * (base_mask - p[Order::A]) + base_mask) >> base_shift)); -+ } - } - }; - -@@ -722,15 +732,18 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type s1a = base_mask - sa; -- calc_type d1a = base_mask - p[Order::A]; -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- p[Order::R] = (value_type)((sr * dr + sr * d1a + dr * s1a + base_mask) >> base_shift); -- p[Order::G] = (value_type)((sg * dg + sg * d1a + dg * s1a + base_mask) >> base_shift); -- p[Order::B] = (value_type)((sb * db + sb * d1a + db * s1a + base_mask) >> base_shift); -- p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type s1a = base_mask - sa; -+ calc_type d1a = base_mask - p[Order::A]; -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ p[Order::R] = (value_type)((sr * dr + sr * d1a + dr * s1a + base_mask) >> base_shift); -+ p[Order::G] = (value_type)((sg * dg + sg * d1a + dg * s1a + base_mask) >> base_shift); -+ p[Order::B] = (value_type)((sb * db + sb * d1a + db * s1a + base_mask) >> base_shift); -+ p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); -+ } - } - }; - -@@ -760,14 +773,17 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- calc_type da = p[Order::A]; -- p[Order::R] = (value_type)(sr + dr - ((sr * dr + base_mask) >> base_shift)); -- p[Order::G] = (value_type)(sg + dg - ((sg * dg + base_mask) >> base_shift)); -- p[Order::B] = (value_type)(sb + db - ((sb * db + base_mask) >> base_shift)); -- p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ calc_type da = p[Order::A]; -+ p[Order::R] = (value_type)(sr + dr - ((sr * dr + base_mask) >> base_shift)); -+ p[Order::G] = (value_type)(sg + dg - ((sg * dg + base_mask) >> base_shift)); -+ p[Order::B] = (value_type)(sb + db - ((sb * db + base_mask) >> base_shift)); -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } - } - }; - -@@ -801,27 +817,30 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type d1a = base_mask - p[Order::A]; -- calc_type s1a = base_mask - sa; -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- calc_type da = p[Order::A]; -- calc_type sada = sa * p[Order::A]; -- -- p[Order::R] = (value_type)(((2*dr < da) ? -- 2*sr*dr + sr*d1a + dr*s1a : -- sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a) >> base_shift); -- -- p[Order::G] = (value_type)(((2*dg < da) ? -- 2*sg*dg + sg*d1a + dg*s1a : -- sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a) >> base_shift); -- -- p[Order::B] = (value_type)(((2*db < da) ? -- 2*sb*db + sb*d1a + db*s1a : -- sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a) >> base_shift); -- -- p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type d1a = base_mask - p[Order::A]; -+ calc_type s1a = base_mask - sa; -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ calc_type da = p[Order::A]; -+ calc_type sada = sa * p[Order::A]; -+ -+ p[Order::R] = (value_type)(((2*dr < da) ? -+ 2*sr*dr + sr*d1a + dr*s1a : -+ sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift); -+ -+ p[Order::G] = (value_type)(((2*dg < da) ? -+ 2*sg*dg + sg*d1a + dg*s1a : -+ sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift); -+ -+ p[Order::B] = (value_type)(((2*db < da) ? -+ 2*sb*db + sb*d1a + db*s1a : -+ sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift); -+ -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } - } - }; - -@@ -855,17 +874,20 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type d1a = base_mask - p[Order::A]; -- calc_type s1a = base_mask - sa; -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- calc_type da = p[Order::A]; -- -- p[Order::R] = (value_type)((sd_min(sr * da, dr * sa) + sr * d1a + dr * s1a) >> base_shift); -- p[Order::G] = (value_type)((sd_min(sg * da, dg * sa) + sg * d1a + dg * s1a) >> base_shift); -- p[Order::B] = (value_type)((sd_min(sb * da, db * sa) + sb * d1a + db * s1a) >> base_shift); -- p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type d1a = base_mask - p[Order::A]; -+ calc_type s1a = base_mask - sa; -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ calc_type da = p[Order::A]; -+ -+ p[Order::R] = (value_type)((sd_min(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift); -+ p[Order::G] = (value_type)((sd_min(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift); -+ p[Order::B] = (value_type)((sd_min(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift); -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } - } - }; - -@@ -895,17 +917,20 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type d1a = base_mask - p[Order::A]; -- calc_type s1a = base_mask - sa; -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- calc_type da = p[Order::A]; -- -- p[Order::R] = (value_type)((sd_max(sr * da, dr * sa) + sr * d1a + dr * s1a) >> base_shift); -- p[Order::G] = (value_type)((sd_max(sg * da, dg * sa) + sg * d1a + dg * s1a) >> base_shift); -- p[Order::B] = (value_type)((sd_max(sb * da, db * sa) + sb * d1a + db * s1a) >> base_shift); -- p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type d1a = base_mask - p[Order::A]; -+ calc_type s1a = base_mask - sa; -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ calc_type da = p[Order::A]; -+ -+ p[Order::R] = (value_type)((sd_max(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift); -+ p[Order::G] = (value_type)((sd_max(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift); -+ p[Order::B] = (value_type)((sd_max(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift); -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } - } - }; - -@@ -940,33 +965,36 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type d1a = base_mask - p[Order::A]; -- calc_type s1a = base_mask - sa; -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- calc_type da = p[Order::A]; -- long_type drsa = dr * sa; -- long_type dgsa = dg * sa; -- long_type dbsa = db * sa; -- long_type srda = sr * da; -- long_type sgda = sg * da; -- long_type sbda = sb * da; -- long_type sada = sa * da; -- -- p[Order::R] = (value_type)((srda + drsa >= sada) ? -- (sada + sr * d1a + dr * s1a) >> base_shift : -- drsa / (base_mask - (sr << base_shift) / sa) + ((sr * d1a + dr * s1a) >> base_shift)); -- -- p[Order::G] = (value_type)((sgda + dgsa >= sada) ? -- (sada + sg * d1a + dg * s1a) >> base_shift : -- dgsa / (base_mask - (sg << base_shift) / sa) + ((sg * d1a + dg * s1a) >> base_shift)); -- -- p[Order::B] = (value_type)((sbda + dbsa >= sada) ? -- (sada + sb * d1a + db * s1a) >> base_shift : -- dbsa / (base_mask - (sb << base_shift) / sa) + ((sb * d1a + db * s1a) >> base_shift)); -- -- p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type d1a = base_mask - p[Order::A]; -+ calc_type s1a = base_mask - sa; -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ calc_type da = p[Order::A]; -+ long_type drsa = dr * sa; -+ long_type dgsa = dg * sa; -+ long_type dbsa = db * sa; -+ long_type srda = sr * da; -+ long_type sgda = sg * da; -+ long_type sbda = sb * da; -+ long_type sada = sa * da; -+ -+ p[Order::R] = (value_type)((srda + drsa >= sada) ? -+ (sada + sr * d1a + dr * s1a + base_mask) >> base_shift : -+ drsa / (base_mask - (sr << base_shift) / sa) + ((sr * d1a + dr * s1a + base_mask) >> base_shift)); -+ -+ p[Order::G] = (value_type)((sgda + dgsa >= sada) ? -+ (sada + sg * d1a + dg * s1a + base_mask) >> base_shift : -+ dgsa / (base_mask - (sg << base_shift) / sa) + ((sg * d1a + dg * s1a + base_mask) >> base_shift)); -+ -+ p[Order::B] = (value_type)((sbda + dbsa >= sada) ? -+ (sada + sb * d1a + db * s1a + base_mask) >> base_shift : -+ dbsa / (base_mask - (sb << base_shift) / sa) + ((sb * d1a + db * s1a + base_mask) >> base_shift)); -+ -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } - } - }; - -@@ -1001,33 +1029,36 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type d1a = base_mask - p[Order::A]; -- calc_type s1a = base_mask - sa; -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- calc_type da = p[Order::A]; -- long_type drsa = dr * sa; -- long_type dgsa = dg * sa; -- long_type dbsa = db * sa; -- long_type srda = sr * da; -- long_type sgda = sg * da; -- long_type sbda = sb * da; -- long_type sada = sa * da; -- -- p[Order::R] = (value_type)(((srda + drsa <= sada) ? -- sr * d1a + dr * s1a : -- sa * (srda + drsa - sada) / sr + sr * d1a + dr * s1a) >> base_shift); -- -- p[Order::G] = (value_type)(((sgda + dgsa <= sada) ? -- sg * d1a + dg * s1a : -- sa * (sgda + dgsa - sada) / sg + sg * d1a + dg * s1a) >> base_shift); -- -- p[Order::B] = (value_type)(((sbda + dbsa <= sada) ? -- sb * d1a + db * s1a : -- sa * (sbda + dbsa - sada) / sb + sb * d1a + db * s1a) >> base_shift); -- -- p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type d1a = base_mask - p[Order::A]; -+ calc_type s1a = base_mask - sa; -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ calc_type da = p[Order::A]; -+ long_type drsa = dr * sa; -+ long_type dgsa = dg * sa; -+ long_type dbsa = db * sa; -+ long_type srda = sr * da; -+ long_type sgda = sg * da; -+ long_type sbda = sb * da; -+ long_type sada = sa * da; -+ -+ p[Order::R] = (value_type)(((srda + drsa <= sada) ? -+ sr * d1a + dr * s1a : -+ sa * (srda + drsa - sada) / sr + sr * d1a + dr * s1a + base_mask) >> base_shift); -+ -+ p[Order::G] = (value_type)(((sgda + dgsa <= sada) ? -+ sg * d1a + dg * s1a : -+ sa * (sgda + dgsa - sada) / sg + sg * d1a + dg * s1a + base_mask) >> base_shift); -+ -+ p[Order::B] = (value_type)(((sbda + dbsa <= sada) ? -+ sb * d1a + db * s1a : -+ sa * (sbda + dbsa - sada) / sb + sb * d1a + db * s1a + base_mask) >> base_shift); -+ -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } - } - }; - -@@ -1062,27 +1093,30 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type d1a = base_mask - p[Order::A]; -- calc_type s1a = base_mask - sa; -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- calc_type da = p[Order::A]; -- calc_type sada = sa * da; -- -- p[Order::R] = (value_type)(((2*sr < sa) ? -- 2*sr*dr + sr*d1a + dr*s1a : -- sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a) >> base_shift); -- -- p[Order::G] = (value_type)(((2*sg < sa) ? -- 2*sg*dg + sg*d1a + dg*s1a : -- sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a) >> base_shift); -- -- p[Order::B] = (value_type)(((2*sb < sa) ? -- 2*sb*db + sb*d1a + db*s1a : -- sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a) >> base_shift); -- -- p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type d1a = base_mask - p[Order::A]; -+ calc_type s1a = base_mask - sa; -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ calc_type da = p[Order::A]; -+ calc_type sada = sa * da; -+ -+ p[Order::R] = (value_type)(((2*sr < sa) ? -+ 2*sr*dr + sr*d1a + dr*s1a : -+ sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift); -+ -+ p[Order::G] = (value_type)(((2*sg < sa) ? -+ 2*sg*dg + sg*d1a + dg*s1a : -+ sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift); -+ -+ p[Order::B] = (value_type)(((2*sb < sa) ? -+ 2*sb*db + sb*d1a + db*s1a : -+ sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift); -+ -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } - } - }; - -@@ -1117,31 +1151,34 @@ namespace agg - double sg = double(g * cover) / (base_mask * 255); - double sb = double(b * cover) / (base_mask * 255); - double sa = double(a * cover) / (base_mask * 255); -- double dr = double(p[Order::R]) / base_mask; -- double dg = double(p[Order::G]) / base_mask; -- double db = double(p[Order::B]) / base_mask; -- double da = double(p[Order::A] ? p[Order::A] : 1) / base_mask; -- if(cover < 255) -+ if(sa > 0) - { -- a = (a * cover + 255) >> 8; -- } -+ double dr = double(p[Order::R]) / base_mask; -+ double dg = double(p[Order::G]) / base_mask; -+ double db = double(p[Order::B]) / base_mask; -+ double da = double(p[Order::A] ? p[Order::A] : 1) / base_mask; -+ if(cover < 255) -+ { -+ a = (a * cover + 255) >> 8; -+ } - -- if(2*sr < sa) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa); -- else if(8*dr <= da) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)*(3 - 8*dr/da)) + sr*(1 - da) + dr*(1 - sa); -- else dr = (dr*sa + (sqrt(dr/da)*da - dr)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa); -+ if(2*sr < sa) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa); -+ else if(8*dr <= da) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)*(3 - 8*dr/da)) + sr*(1 - da) + dr*(1 - sa); -+ else dr = (dr*sa + (sqrt(dr/da)*da - dr)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa); - -- if(2*sg < sa) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa); -- else if(8*dg <= da) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)*(3 - 8*dg/da)) + sg*(1 - da) + dg*(1 - sa); -- else dg = (dg*sa + (sqrt(dg/da)*da - dg)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa); -+ if(2*sg < sa) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa); -+ else if(8*dg <= da) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)*(3 - 8*dg/da)) + sg*(1 - da) + dg*(1 - sa); -+ else dg = (dg*sa + (sqrt(dg/da)*da - dg)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa); - -- if(2*sb < sa) db = db*(sa + (1 - db/da)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa); -- else if(8*db <= da) db = db*(sa + (1 - db/da)*(2*sb - sa)*(3 - 8*db/da)) + sb*(1 - da) + db*(1 - sa); -- else db = (db*sa + (sqrt(db/da)*da - db)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa); -+ if(2*sb < sa) db = db*(sa + (1 - db/da)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa); -+ else if(8*db <= da) db = db*(sa + (1 - db/da)*(2*sb - sa)*(3 - 8*db/da)) + sb*(1 - da) + db*(1 - sa); -+ else db = (db*sa + (sqrt(db/da)*da - db)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa); - -- p[Order::R] = (value_type)uround(dr * base_mask); -- p[Order::G] = (value_type)uround(dg * base_mask); -- p[Order::B] = (value_type)uround(db * base_mask); -- p[Order::A] = (value_type)(a + p[Order::A] - ((a * p[Order::A] + base_mask) >> base_shift)); -+ p[Order::R] = (value_type)uround(dr * base_mask); -+ p[Order::G] = (value_type)uround(dg * base_mask); -+ p[Order::B] = (value_type)uround(db * base_mask); -+ p[Order::A] = (value_type)(a + p[Order::A] - ((a * p[Order::A] + base_mask) >> base_shift)); -+ } - } - }; - -@@ -1156,6 +1193,7 @@ namespace agg - enum base_scale_e - { - base_shift = color_type::base_shift, -+ base_scale = color_type::base_scale, - base_mask = color_type::base_mask - }; - -@@ -1172,14 +1210,17 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- calc_type da = p[Order::A]; -- p[Order::R] = (value_type)(sr + dr - ((2 * sd_min(sr*da, dr*sa)) >> base_shift)); -- p[Order::G] = (value_type)(sg + dg - ((2 * sd_min(sg*da, dg*sa)) >> base_shift)); -- p[Order::B] = (value_type)(sb + db - ((2 * sd_min(sb*da, db*sa)) >> base_shift)); -- p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ calc_type da = p[Order::A]; -+ p[Order::R] = (value_type)(sr + dr - ((2 * sd_min(sr*da, dr*sa) + base_mask) >> base_shift)); -+ p[Order::G] = (value_type)(sg + dg - ((2 * sd_min(sg*da, dg*sa) + base_mask) >> base_shift)); -+ p[Order::B] = (value_type)(sb + db - ((2 * sd_min(sb*da, db*sa) + base_mask) >> base_shift)); -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } - } - }; - -@@ -1210,16 +1251,19 @@ namespace agg - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } -- calc_type d1a = base_mask - p[Order::A]; -- calc_type s1a = base_mask - sa; -- calc_type dr = p[Order::R]; -- calc_type dg = p[Order::G]; -- calc_type db = p[Order::B]; -- calc_type da = p[Order::A]; -- p[Order::R] = (value_type)((sr*da + dr*sa - 2*sr*dr + sr*d1a + dr*s1a) >> base_shift); -- p[Order::G] = (value_type)((sg*da + dg*sa - 2*sg*dg + sg*d1a + dg*s1a) >> base_shift); -- p[Order::B] = (value_type)((sb*da + db*sa - 2*sb*db + sb*d1a + db*s1a) >> base_shift); -- p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ if(sa) -+ { -+ calc_type d1a = base_mask - p[Order::A]; -+ calc_type s1a = base_mask - sa; -+ calc_type dr = p[Order::R]; -+ calc_type dg = p[Order::G]; -+ calc_type db = p[Order::B]; -+ calc_type da = p[Order::A]; -+ p[Order::R] = (value_type)((sr*da + dr*sa - 2*sr*dr + sr*d1a + dr*s1a + base_mask) >> base_shift); -+ p[Order::G] = (value_type)((sg*da + dg*sa - 2*sg*dg + sg*d1a + dg*s1a + base_mask) >> base_shift); -+ p[Order::B] = (value_type)((sb*da + db*sa - 2*sb*db + sb*d1a + db*s1a + base_mask) >> base_shift); -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } - } - }; - -@@ -1270,11 +1314,83 @@ namespace agg - } - }; - -+ //=====================================================comp_op_rgba_invert -+ template struct comp_op_rgba_invert -+ { -+ typedef ColorT color_type; -+ typedef Order order_type; -+ typedef typename color_type::value_type value_type; -+ typedef typename color_type::calc_type calc_type; -+ typedef typename color_type::long_type long_type; -+ enum base_scale_e -+ { -+ base_shift = color_type::base_shift, -+ base_mask = color_type::base_mask -+ }; - -+ // Dca' = (Da - Dca) * Sa + Dca.(1 - Sa) -+ // Da' = Sa + Da - Sa.Da -+ static AGG_INLINE void blend_pix(value_type* p, -+ unsigned sr, unsigned sg, unsigned sb, -+ unsigned sa, unsigned cover) -+ { -+ sa = (sa * cover + 255) >> 8; -+ if(sa) -+ { -+ calc_type da = p[Order::A]; -+ calc_type dr = ((da - p[Order::R]) * sa + base_mask) >> base_shift; -+ calc_type dg = ((da - p[Order::G]) * sa + base_mask) >> base_shift; -+ calc_type db = ((da - p[Order::B]) * sa + base_mask) >> base_shift; -+ calc_type s1a = base_mask - sa; -+ p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift)); -+ p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift)); -+ p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift)); -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } -+ } -+ }; - -+ //=================================================comp_op_rgba_invert_rgb -+ template struct comp_op_rgba_invert_rgb -+ { -+ typedef ColorT color_type; -+ typedef Order order_type; -+ typedef typename color_type::value_type value_type; -+ typedef typename color_type::calc_type calc_type; -+ typedef typename color_type::long_type long_type; -+ enum base_scale_e -+ { -+ base_shift = color_type::base_shift, -+ base_mask = color_type::base_mask -+ }; - -- -- -+ // Dca' = (Da - Dca) * Sca + Dca.(1 - Sa) -+ // Da' = Sa + Da - Sa.Da -+ static AGG_INLINE void blend_pix(value_type* p, -+ unsigned sr, unsigned sg, unsigned sb, -+ unsigned sa, unsigned cover) -+ { -+ if(cover < 255) -+ { -+ sr = (sr * cover + 255) >> 8; -+ sg = (sg * cover + 255) >> 8; -+ sb = (sb * cover + 255) >> 8; -+ sa = (sa * cover + 255) >> 8; -+ } -+ if(sa) -+ { -+ calc_type da = p[Order::A]; -+ calc_type dr = ((da - p[Order::R]) * sr + base_mask) >> base_shift; -+ calc_type dg = ((da - p[Order::G]) * sg + base_mask) >> base_shift; -+ calc_type db = ((da - p[Order::B]) * sb + base_mask) >> base_shift; -+ calc_type s1a = base_mask - sa; -+ p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift)); -+ p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift)); -+ p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift)); -+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); -+ } -+ } -+ }; - - - -@@ -1324,6 +1440,8 @@ namespace agg - comp_op_rgba_difference ::blend_pix, - comp_op_rgba_exclusion ::blend_pix, - comp_op_rgba_contrast ::blend_pix, -+ comp_op_rgba_invert ::blend_pix, -+ comp_op_rgba_invert_rgb ::blend_pix, - 0 - }; - -@@ -1357,6 +1475,8 @@ namespace agg - comp_op_difference, //----comp_op_difference - comp_op_exclusion, //----comp_op_exclusion - comp_op_contrast, //----comp_op_contrast -+ comp_op_invert, //----comp_op_invert -+ comp_op_invert_rgb, //----comp_op_invert_rgb - - end_of_comp_op_e - }; -@@ -1655,28 +1775,45 @@ namespace agg - pixfmt_alpha_blend_rgba(rbuf_type& rb) : m_rbuf(&rb) {} - void attach(rbuf_type& rb) { m_rbuf = &rb; } - -+ //-------------------------------------------------------------------- -+ template -+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) -+ { -+ rect_i r(x1, y1, x2, y2); -+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) -+ { -+ int stride = pixf.stride(); -+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), -+ (r.x2 - r.x1) + 1, -+ (r.y2 - r.y1) + 1, -+ stride); -+ return true; -+ } -+ return false; -+ } -+ - //-------------------------------------------------------------------- - AGG_INLINE unsigned width() const { return m_rbuf->width(); } - AGG_INLINE unsigned height() const { return m_rbuf->height(); } -+ AGG_INLINE int stride() const { return m_rbuf->stride(); } - - //-------------------------------------------------------------------- -- const int8u* row_ptr(int y) const -- { -- return m_rbuf->row_ptr(y); -- } -+ AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } -+ AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } -+ AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } - - //-------------------------------------------------------------------- -- const int8u* pix_ptr(int x, int y) const -+ AGG_INLINE int8u* pix_ptr(int x, int y) - { - return m_rbuf->row_ptr(y) + x * pix_width; - } - -- //-------------------------------------------------------------------- -- row_data row(int y) const -+ AGG_INLINE const int8u* pix_ptr(int x, int y) const - { -- return m_rbuf->row(y); -+ return m_rbuf->row_ptr(y) + x * pix_width; - } - -+ - //-------------------------------------------------------------------- - AGG_INLINE static void make_pix(int8u* p, const color_type& c) - { -@@ -1828,8 +1965,8 @@ namespace agg - ((value_type*)&v)[order_type::A] = c.a; - do - { -+ p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - *(pixel_type*)p = v; -- p = (value_type*)m_rbuf->next_row(p); - } - while(--len); - } -@@ -1938,6 +2075,24 @@ namespace agg - } - - -+ //-------------------------------------------------------------------- -+ void copy_color_vspan(int x, int y, -+ unsigned len, -+ const color_type* colors) -+ { -+ do -+ { -+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); -+ p[order_type::R] = colors->r; -+ p[order_type::G] = colors->g; -+ p[order_type::B] = colors->b; -+ p[order_type::A] = colors->a; -+ ++colors; -+ } -+ while(--len); -+ } -+ -+ - //-------------------------------------------------------------------- - void blend_color_hspan(int x, int y, - unsigned len, -@@ -2206,31 +2361,47 @@ namespace agg - void attach(rbuf_type& rb) { m_rbuf = &rb; } - - //-------------------------------------------------------------------- -- unsigned width() const { return m_rbuf->width(); } -- unsigned height() const { return m_rbuf->height(); } -+ template -+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) -+ { -+ rect_i r(x1, y1, x2, y2); -+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) -+ { -+ int stride = pixf.stride(); -+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), -+ (r.x2 - r.x1) + 1, -+ (r.y2 - r.y1) + 1, -+ stride); -+ return true; -+ } -+ return false; -+ } - - //-------------------------------------------------------------------- -- void comp_op(unsigned op) { m_comp_op = op; } -- unsigned comp_op() const { return m_comp_op; } -+ AGG_INLINE unsigned width() const { return m_rbuf->width(); } -+ AGG_INLINE unsigned height() const { return m_rbuf->height(); } -+ AGG_INLINE int stride() const { return m_rbuf->stride(); } - - //-------------------------------------------------------------------- -- const int8u* row_ptr(int y) const -- { -- return m_rbuf->row_ptr(y); -- } -+ AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } -+ AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } -+ AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } - - //-------------------------------------------------------------------- -- const int8u* pix_ptr(int x, int y) const -+ AGG_INLINE int8u* pix_ptr(int x, int y) - { - return m_rbuf->row_ptr(y) + x * pix_width; - } - -- //-------------------------------------------------------------------- -- row_data row(int x, int y) const -+ AGG_INLINE const int8u* pix_ptr(int x, int y) const - { -- return m_rbuf->row(y); -+ return m_rbuf->row_ptr(y) + x * pix_width; - } - -+ //-------------------------------------------------------------------- -+ void comp_op(unsigned op) { m_comp_op = op; } -+ unsigned comp_op() const { return m_comp_op; } -+ - //-------------------------------------------------------------------- - AGG_INLINE static void make_pix(int8u* p, const color_type& c) - { -@@ -2373,6 +2544,23 @@ namespace agg - while(--len); - } - -+ //-------------------------------------------------------------------- -+ void copy_color_vspan(int x, int y, -+ unsigned len, -+ const color_type* colors) -+ { -+ do -+ { -+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); -+ p[order_type::R] = colors->r; -+ p[order_type::G] = colors->g; -+ p[order_type::B] = colors->b; -+ p[order_type::A] = colors->a; -+ ++colors; -+ } -+ while(--len); -+ } -+ - //-------------------------------------------------------------------- - void blend_color_hspan(int x, int y, unsigned len, - const color_type* colors, -diff --git a/src/third_party/agg/include/agg_pixfmt_transposer.h b/src/third_party/agg/include/agg_pixfmt_transposer.h -new file mode 100644 -index 0000000..723da7b ---- /dev/null -+++ b/src/third_party/agg/include/agg_pixfmt_transposer.h -@@ -0,0 +1,157 @@ -+//---------------------------------------------------------------------------- -+// Anti-Grain Geometry - Version 2.4 -+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -+// -+// Permission to copy, use, modify, sell and distribute this software -+// is granted provided this copyright notice appears in all copies. -+// This software is provided "as is" without express or implied -+// warranty, and with no claim as to its suitability for any purpose. -+// -+//---------------------------------------------------------------------------- -+// Contact: mcseem@antigrain.com -+// mcseemagg@yahoo.com -+// http://www.antigrain.com -+//---------------------------------------------------------------------------- -+ -+#ifndef AGG_PIXFMT_TRANSPOSER_INCLUDED -+#define AGG_PIXFMT_TRANSPOSER_INCLUDED -+ -+#include "agg_basics.h" -+ -+namespace agg -+{ -+ //=======================================================pixfmt_transposer -+ template class pixfmt_transposer -+ { -+ public: -+ typedef PixFmt pixfmt_type; -+ typedef typename pixfmt_type::color_type color_type; -+ typedef typename pixfmt_type::row_data row_data; -+ typedef typename color_type::value_type value_type; -+ typedef typename color_type::calc_type calc_type; -+ -+ //-------------------------------------------------------------------- -+ pixfmt_transposer() : m_pixf(0) {} -+ pixfmt_transposer(pixfmt_type& pixf) : m_pixf(&pixf) {} -+ void attach(pixfmt_type& pixf) { m_pixf = &pixf; } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE unsigned width() const { return m_pixf->height(); } -+ AGG_INLINE unsigned height() const { return m_pixf->width(); } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE color_type pixel(int x, int y) const -+ { -+ return m_pixf->pixel(y, x); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void copy_pixel(int x, int y, const color_type& c) -+ { -+ m_pixf->copy_pixel(y, x, c); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void blend_pixel(int x, int y, -+ const color_type& c, -+ int8u cover) -+ { -+ m_pixf->blend_pixel(y, x, c, cover); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void copy_hline(int x, int y, -+ unsigned len, -+ const color_type& c) -+ { -+ m_pixf->copy_vline(y, x, len, c); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void copy_vline(int x, int y, -+ unsigned len, -+ const color_type& c) -+ { -+ m_pixf->copy_hline(y, x, len, c); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void blend_hline(int x, int y, -+ unsigned len, -+ const color_type& c, -+ int8u cover) -+ { -+ m_pixf->blend_vline(y, x, len, c, cover); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void blend_vline(int x, int y, -+ unsigned len, -+ const color_type& c, -+ int8u cover) -+ { -+ m_pixf->blend_hline(y, x, len, c, cover); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void blend_solid_hspan(int x, int y, -+ unsigned len, -+ const color_type& c, -+ const int8u* covers) -+ { -+ m_pixf->blend_solid_vspan(y, x, len, c, covers); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void blend_solid_vspan(int x, int y, -+ unsigned len, -+ const color_type& c, -+ const int8u* covers) -+ { -+ m_pixf->blend_solid_hspan(y, x, len, c, covers); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void copy_color_hspan(int x, int y, -+ unsigned len, -+ const color_type* colors) -+ { -+ m_pixf->copy_color_vspan(y, x, len, colors); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void copy_color_vspan(int x, int y, -+ unsigned len, -+ const color_type* colors) -+ { -+ m_pixf->copy_color_hspan(y, x, len, colors); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void blend_color_hspan(int x, int y, -+ unsigned len, -+ const color_type* colors, -+ const int8u* covers, -+ int8u cover) -+ { -+ m_pixf->blend_color_vspan(y, x, len, colors, covers, cover); -+ } -+ -+ //-------------------------------------------------------------------- -+ AGG_INLINE void blend_color_vspan(int x, int y, -+ unsigned len, -+ const color_type* colors, -+ const int8u* covers, -+ int8u cover) -+ { -+ m_pixf->blend_color_hspan(y, x, len, colors, covers, cover); -+ } -+ -+ private: -+ pixfmt_type* m_pixf; -+ }; -+} -+ -+#endif -+ -+ -diff --git a/src/third_party/agg/include/agg_rasterizer_cells_aa.h b/src/third_party/agg/include/agg_rasterizer_cells_aa.h -old mode 100755 -new mode 100644 -index 5455e55..59ffd77 ---- a/src/third_party/agg/include/agg_rasterizer_cells_aa.h -+++ b/src/third_party/agg/include/agg_rasterizer_cells_aa.h -@@ -103,21 +103,21 @@ namespace agg - void allocate_block(); - - private: -- unsigned m_num_blocks; -- unsigned m_max_blocks; -- unsigned m_curr_block; -- unsigned m_num_cells; -- cell_type** m_cells; -- cell_type* m_curr_cell_ptr; -- pod_vector m_sorted_cells; -- pod_vector m_sorted_y; -- cell_type m_curr_cell; -- cell_type m_style_cell; -- int m_min_x; -- int m_min_y; -- int m_max_x; -- int m_max_y; -- bool m_sorted; -+ unsigned m_num_blocks; -+ unsigned m_max_blocks; -+ unsigned m_curr_block; -+ unsigned m_num_cells; -+ cell_type** m_cells; -+ cell_type* m_curr_cell_ptr; -+ pod_vector m_sorted_cells; -+ pod_vector m_sorted_y; -+ cell_type m_curr_cell; -+ cell_type m_style_cell; -+ int m_min_x; -+ int m_min_y; -+ int m_max_x; -+ int m_max_y; -+ bool m_sorted; - }; - - -@@ -132,10 +132,10 @@ namespace agg - cell_type** ptr = m_cells + m_num_blocks - 1; - while(m_num_blocks--) - { -- delete [] *ptr; -+ pod_allocator::deallocate(*ptr, cell_block_size); - ptr--; - } -- delete [] m_cells; -+ pod_allocator::deallocate(m_cells, m_max_blocks); - } - } - -@@ -188,10 +188,6 @@ namespace agg - } - *m_curr_cell_ptr++ = m_curr_cell; - ++m_num_cells; -- //if(m_curr_cell.x < m_min_x) m_min_x = m_curr_cell.x; -- //if(m_curr_cell.x > m_max_x) m_max_x = m_curr_cell.x; -- //if(m_curr_cell.y < m_min_y) m_min_y = m_curr_cell.y; -- //if(m_curr_cell.y > m_max_y) m_max_y = m_curr_cell.y; - } - } - -@@ -474,16 +470,22 @@ namespace agg - { - if(m_num_blocks >= m_max_blocks) - { -- cell_type** new_cells = new cell_type* [m_max_blocks + cell_block_pool]; -+ cell_type** new_cells = -+ pod_allocator::allocate(m_max_blocks + -+ cell_block_pool); -+ - if(m_cells) - { - memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*)); -- delete [] m_cells; -+ pod_allocator::deallocate(m_cells, m_max_blocks); - } - m_cells = new_cells; - m_max_blocks += cell_block_pool; - } -- m_cells[m_num_blocks++] = new cell_type [unsigned(cell_block_size)]; -+ -+ m_cells[m_num_blocks++] = -+ pod_allocator::allocate(cell_block_size); -+ - } - m_curr_cell_ptr = m_cells[m_curr_block++]; - } -@@ -721,6 +723,33 @@ namespace agg - m_sorted = true; - } - -+ -+ -+ //------------------------------------------------------scanline_hit_test -+ class scanline_hit_test -+ { -+ public: -+ scanline_hit_test(int x) : m_x(x), m_hit(false) {} -+ -+ void reset_spans() {} -+ void finalize(int) {} -+ void add_cell(int x, int) -+ { -+ if(m_x == x) m_hit = true; -+ } -+ void add_span(int x, int len, int) -+ { -+ if(m_x >= x && m_x < x+len) m_hit = true; -+ } -+ unsigned num_spans() const { return 1; } -+ bool hit() const { return m_hit; } -+ -+ private: -+ int m_x; -+ bool m_hit; -+ }; -+ -+ - } - - #endif -diff --git a/src/third_party/agg/include/agg_rasterizer_compound_aa.h b/src/third_party/agg/include/agg_rasterizer_compound_aa.h -old mode 100755 -new mode 100644 -index c6c69e2..8547747 ---- a/src/third_party/agg/include/agg_rasterizer_compound_aa.h -+++ b/src/third_party/agg/include/agg_rasterizer_compound_aa.h -@@ -86,33 +86,45 @@ namespace agg - }; - - public: -- typedef Clip clip_type; -- typedef typename Clip::conv_type conv_type; -+ typedef Clip clip_type; -+ typedef typename Clip::conv_type conv_type; -+ typedef typename Clip::coord_type coord_type; - - enum aa_scale_e - { - aa_shift = 8, - aa_scale = 1 << aa_shift, -- aa_mask = aa_scale - 1 -+ aa_mask = aa_scale - 1, -+ aa_scale2 = aa_scale * 2, -+ aa_mask2 = aa_scale2 - 1 - }; - - //-------------------------------------------------------------------- - rasterizer_compound_aa() : - m_outline(), - m_clipper(), -+ m_filling_rule(fill_non_zero), - m_styles(), // Active Styles - m_ast(), // Active Style Table (unique values) - m_asm(), // Active Style Mask - m_cells(), -+ m_cover_buf(), -+ m_master_alpha(), - m_min_style(0x7FFFFFFF), - m_max_style(-0x7FFFFFFF), -- m_scan_y(0x7FFFFFFF) -+ m_start_x(0), -+ m_start_y(0), -+ m_scan_y(0x7FFFFFFF), -+ m_sl_start(0), -+ m_sl_len(0) - {} - - //-------------------------------------------------------------------- - void reset(); - void reset_clipping(); - void clip_box(double x1, double y1, double x2, double y2); -+ void filling_rule(filling_rule_e filling_rule); -+ void master_alpha(int style, double alpha); - - //-------------------------------------------------------------------- - void styles(int left, int right); -@@ -154,15 +166,31 @@ namespace agg - void sort(); - bool rewind_scanlines(); - unsigned sweep_styles(); -+ int scanline_start() const { return m_sl_start; } -+ unsigned scanline_length() const { return m_sl_len; } - unsigned style(unsigned style_idx) const; - -+ cover_type* allocate_cover_buffer(unsigned len); -+ -+ //-------------------------------------------------------------------- -+ bool navigate_scanline(int y); -+ bool hit_test(int tx, int ty); -+ - //-------------------------------------------------------------------- -- AGG_INLINE unsigned calculate_alpha(int area) const -+ AGG_INLINE unsigned calculate_alpha(int area, unsigned master_alpha) const - { - int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift); - if(cover < 0) cover = -cover; -+ if(m_filling_rule == fill_even_odd) -+ { -+ cover &= aa_mask2; -+ if(cover > aa_scale) -+ { -+ cover = aa_scale2 - cover; -+ } -+ } - if(cover > aa_mask) cover = aa_mask; -- return cover; -+ return (cover * master_alpha + aa_mask) >> aa_shift; - } - - //-------------------------------------------------------------------- -@@ -175,8 +203,17 @@ namespace agg - - sl.reset_spans(); - -- if(style_idx < 0) style_idx = 0; -- else style_idx++; -+ unsigned master_alpha = aa_mask; -+ -+ if(style_idx < 0) -+ { -+ style_idx = 0; -+ } -+ else -+ { -+ style_idx++; -+ master_alpha = m_master_alpha[m_ast[style_idx] + m_min_style - 1]; -+ } - - const style_info& st = m_styles[m_ast[style_idx]]; - -@@ -196,14 +233,16 @@ namespace agg - - if(area) - { -- alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area); -+ alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area, -+ master_alpha); - sl.add_cell(x, alpha); - x++; - } - - if(num_cells && cell->x > x) - { -- alpha = calculate_alpha(cover << (poly_subpixel_shift + 1)); -+ alpha = calculate_alpha(cover << (poly_subpixel_shift + 1), -+ master_alpha); - if(alpha) - { - sl.add_span(x, cell->x - x, alpha); -@@ -214,11 +253,11 @@ namespace agg - if(sl.num_spans() == 0) return false; - sl.finalize(scan_y); - return true; -- - } - - private: - void add_style(int style_id); -+ void allocate_master_alpha(); - - //-------------------------------------------------------------------- - // Disable copying -@@ -229,14 +268,21 @@ namespace agg - private: - rasterizer_cells_aa m_outline; - clip_type m_clipper; -+ filling_rule_e m_filling_rule; - pod_vector m_styles; // Active Styles - pod_vector m_ast; // Active Style Table (unique values) - pod_vector m_asm; // Active Style Mask - pod_vector m_cells; -- -- int m_min_style; -- int m_max_style; -- int m_scan_y; -+ pod_vector m_cover_buf; -+ pod_bvector m_master_alpha; -+ -+ int m_min_style; -+ int m_max_style; -+ coord_type m_start_x; -+ coord_type m_start_y; -+ int m_scan_y; -+ int m_sl_start; -+ unsigned m_sl_len; - }; - - -@@ -256,6 +302,15 @@ namespace agg - m_min_style = 0x7FFFFFFF; - m_max_style = -0x7FFFFFFF; - m_scan_y = 0x7FFFFFFF; -+ m_sl_start = 0; -+ m_sl_len = 0; -+ } -+ -+ //------------------------------------------------------------------------ -+ template -+ void rasterizer_compound_aa::filling_rule(filling_rule_e filling_rule) -+ { -+ m_filling_rule = filling_rule; - } - - //------------------------------------------------------------------------ -@@ -296,7 +351,8 @@ namespace agg - void rasterizer_compound_aa::move_to(int x, int y) - { - if(m_outline.sorted()) reset(); -- m_clipper.move_to(conv_type::downscale(x), conv_type::downscale(y)); -+ m_clipper.move_to(m_start_x = conv_type::downscale(x), -+ m_start_y = conv_type::downscale(y)); - } - - //------------------------------------------------------------------------ -@@ -313,7 +369,8 @@ namespace agg - void rasterizer_compound_aa::move_to_d(double x, double y) - { - if(m_outline.sorted()) reset(); -- m_clipper.move_to(conv_type::upscale(x), conv_type::upscale(y)); -+ m_clipper.move_to(m_start_x = conv_type::upscale(x), -+ m_start_y = conv_type::upscale(y)); - } - - //------------------------------------------------------------------------ -@@ -334,11 +391,14 @@ namespace agg - move_to_d(x, y); - } - else -+ if(is_vertex(cmd)) - { -- if(is_vertex(cmd)) -- { -- line_to_d(x, y); -- } -+ line_to_d(x, y); -+ } -+ else -+ if(is_close(cmd)) -+ { -+ m_clipper.line_to(m_outline, m_start_x, m_start_y); - } - } - -@@ -387,6 +447,7 @@ namespace agg - } - m_scan_y = m_outline.min_y(); - m_styles.allocate(m_max_style - m_min_style + 2, 128); -+ allocate_master_alpha(); - return true; - } - -@@ -433,83 +494,92 @@ namespace agg - m_asm.allocate((num_styles + 7) >> 3, 8); - m_asm.zero(); - -- // Pre-add zero (for no-fill style, that is, -1). -- // We need that to ensure that the "-1 style" would go first. -- m_asm[0] |= 1; -- m_ast.add(0); -- style = &m_styles[0]; -- style->start_cell = 0; -- style->num_cells = 0; -- style->last_x = -0x7FFFFFFF; -- -- while(num_cells--) -+ if(num_cells) - { -- curr_cell = *cells++; -- add_style(curr_cell->left); -- add_style(curr_cell->right); -- } -- -- // Convert the Y-histogram into the array of starting indexes -- unsigned i; -- unsigned start_cell = 0; -- for(i = 0; i < m_ast.size(); i++) -- { -- style_info& st = m_styles[m_ast[i]]; -- unsigned v = st.start_cell; -- st.start_cell = start_cell; -- start_cell += v; -- } -- -- cells = m_outline.scanline_cells(m_scan_y); -- num_cells = m_outline.scanline_num_cells(m_scan_y); -- -- while(num_cells--) -- { -- curr_cell = *cells++; -- style_id = (curr_cell->left < 0) ? 0 : -- curr_cell->left - m_min_style + 1; -- -- style = &m_styles[style_id]; -- if(curr_cell->x == style->last_x) -+ // Pre-add zero (for no-fill style, that is, -1). -+ // We need that to ensure that the "-1 style" would go first. -+ m_asm[0] |= 1; -+ m_ast.add(0); -+ style = &m_styles[0]; -+ style->start_cell = 0; -+ style->num_cells = 0; -+ style->last_x = -0x7FFFFFFF; -+ -+ m_sl_start = cells[0]->x; -+ m_sl_len = cells[num_cells-1]->x - m_sl_start + 1; -+ while(num_cells--) - { -- cell = &m_cells[style->start_cell + style->num_cells - 1]; -- cell->area += curr_cell->area; -- cell->cover += curr_cell->cover; -+ curr_cell = *cells++; -+ add_style(curr_cell->left); -+ add_style(curr_cell->right); - } -- else -+ -+ // Convert the Y-histogram into the array of starting indexes -+ unsigned i; -+ unsigned start_cell = 0; -+ for(i = 0; i < m_ast.size(); i++) - { -- cell = &m_cells[style->start_cell + style->num_cells]; -- cell->x = curr_cell->x; -- cell->area = curr_cell->area; -- cell->cover = curr_cell->cover; -- style->last_x = curr_cell->x; -- style->num_cells++; -+ style_info& st = m_styles[m_ast[i]]; -+ unsigned v = st.start_cell; -+ st.start_cell = start_cell; -+ start_cell += v; - } - -- style_id = (curr_cell->right < 0) ? 0 : -- curr_cell->right - m_min_style + 1; -+ cells = m_outline.scanline_cells(m_scan_y); -+ num_cells = m_outline.scanline_num_cells(m_scan_y); - -- style = &m_styles[style_id]; -- if(curr_cell->x == style->last_x) -+ while(num_cells--) - { -- cell = &m_cells[style->start_cell + style->num_cells - 1]; -- cell->area -= curr_cell->area; -- cell->cover -= curr_cell->cover; -- } -- else -- { -- cell = &m_cells[style->start_cell + style->num_cells]; -- cell->x = curr_cell->x; -- cell->area = -curr_cell->area; -- cell->cover = -curr_cell->cover; -- style->last_x = curr_cell->x; -- style->num_cells++; -+ curr_cell = *cells++; -+ style_id = (curr_cell->left < 0) ? 0 : -+ curr_cell->left - m_min_style + 1; -+ -+ style = &m_styles[style_id]; -+ if(curr_cell->x == style->last_x) -+ { -+ cell = &m_cells[style->start_cell + style->num_cells - 1]; -+ cell->area += curr_cell->area; -+ cell->cover += curr_cell->cover; -+ } -+ else -+ { -+ cell = &m_cells[style->start_cell + style->num_cells]; -+ cell->x = curr_cell->x; -+ cell->area = curr_cell->area; -+ cell->cover = curr_cell->cover; -+ style->last_x = curr_cell->x; -+ style->num_cells++; -+ } -+ -+ style_id = (curr_cell->right < 0) ? 0 : -+ curr_cell->right - m_min_style + 1; -+ -+ style = &m_styles[style_id]; -+ if(curr_cell->x == style->last_x) -+ { -+ cell = &m_cells[style->start_cell + style->num_cells - 1]; -+ cell->area -= curr_cell->area; -+ cell->cover -= curr_cell->cover; -+ } -+ else -+ { -+ cell = &m_cells[style->start_cell + style->num_cells]; -+ cell->x = curr_cell->x; -+ cell->area = -curr_cell->area; -+ cell->cover = -curr_cell->cover; -+ style->last_x = curr_cell->x; -+ style->num_cells++; -+ } - } - } - if(m_ast.size() > 1) break; - ++m_scan_y; - } - ++m_scan_y; -+ -+ range_adaptor > ra(m_ast, 1, m_ast.size() - 1); -+ quick_sort(ra, unsigned_greater); -+ - return m_ast.size() - 1; - } - -@@ -522,6 +592,80 @@ namespace agg - return m_ast[style_idx + 1] + m_min_style - 1; - } - -+ //------------------------------------------------------------------------ -+ template -+ AGG_INLINE bool rasterizer_compound_aa::navigate_scanline(int y) -+ { -+ m_outline.sort_cells(); -+ if(m_outline.total_cells() == 0) -+ { -+ return false; -+ } -+ if(m_max_style < m_min_style) -+ { -+ return false; -+ } -+ if(y < m_outline.min_y() || y > m_outline.max_y()) -+ { -+ return false; -+ } -+ m_scan_y = y; -+ m_styles.allocate(m_max_style - m_min_style + 2, 128); -+ allocate_master_alpha(); -+ return true; -+ } -+ -+ //------------------------------------------------------------------------ -+ template -+ bool rasterizer_compound_aa::hit_test(int tx, int ty) -+ { -+ if(!navigate_scanline(ty)) -+ { -+ return false; -+ } -+ -+ unsigned num_styles = sweep_styles(); -+ if(num_styles <= 0) -+ { -+ return false; -+ } -+ -+ scanline_hit_test sl(tx); -+ sweep_scanline(sl, -1); -+ return sl.hit(); -+ } -+ -+ //------------------------------------------------------------------------ -+ template -+ cover_type* rasterizer_compound_aa::allocate_cover_buffer(unsigned len) -+ { -+ m_cover_buf.allocate(len, 256); -+ return &m_cover_buf[0]; -+ } -+ -+ //------------------------------------------------------------------------ -+ template -+ void rasterizer_compound_aa::allocate_master_alpha() -+ { -+ while((int)m_master_alpha.size() <= m_max_style) -+ { -+ m_master_alpha.add(aa_mask); -+ } -+ } -+ -+ //------------------------------------------------------------------------ -+ template -+ void rasterizer_compound_aa::master_alpha(int style, double alpha) -+ { -+ if(style >= 0) -+ { -+ while((int)m_master_alpha.size() <= style) -+ { -+ m_master_alpha.add(aa_mask); -+ } -+ m_master_alpha[style] = uround(alpha * aa_mask); -+ } -+ } - - } - -diff --git a/src/third_party/agg/include/agg_rasterizer_outline.h b/src/third_party/agg/include/agg_rasterizer_outline.h -index e2dea2a..cc2bd2f 100644 ---- a/src/third_party/agg/include/agg_rasterizer_outline.h -+++ b/src/third_party/agg/include/agg_rasterizer_outline.h -@@ -28,8 +28,9 @@ namespace agg - m_start_x(0), - m_start_y(0), - m_vertices(0) -- { -- } -+ {} -+ void attach(Renderer& ren) { m_ren = &ren; } -+ - - //-------------------------------------------------------------------- - void move_to(int x, int y) -diff --git a/src/third_party/agg/include/agg_rasterizer_outline_aa.h b/src/third_party/agg/include/agg_rasterizer_outline_aa.h -index d06a80f..6ce3c31 100644 ---- a/src/third_party/agg/include/agg_rasterizer_outline_aa.h -+++ b/src/third_party/agg/include/agg_rasterizer_outline_aa.h -@@ -86,20 +86,20 @@ namespace agg - typedef vertex_sequence vertex_storage_type; - - rasterizer_outline_aa(Renderer& ren) : -- m_ren(ren), -+ m_ren(&ren), - m_line_join(ren.accurate_join_only() ? - outline_miter_accurate_join : - outline_round_join), - m_round_cap(false), - m_start_x(0), - m_start_y(0) -- { -- } -+ {} -+ void attach(Renderer& ren) { m_ren = &ren; } - - //------------------------------------------------------------------------ - void line_join(outline_aa_join_e join) - { -- m_line_join = m_ren.accurate_join_only() ? -+ m_line_join = m_ren->accurate_join_only() ? - outline_miter_accurate_join : - join; - } -@@ -187,7 +187,7 @@ namespace agg - { - for(unsigned i = 0; i < num_paths; i++) - { -- m_ren.color(colors[i]); -+ m_ren->color(colors[i]); - add_path(vs, path_id[i]); - } - } -@@ -199,7 +199,7 @@ namespace agg - unsigned i; - for(i = 0; i < c.num_paths(); i++) - { -- m_ren.color(c.color(i)); -+ m_ren->color(c.color(i)); - add_path(c, i); - } - } -@@ -209,7 +209,7 @@ namespace agg - const rasterizer_outline_aa& operator = - (const rasterizer_outline_aa&); - -- Renderer& m_ren; -+ Renderer* m_ren; - vertex_storage_type m_src_vertices; - outline_aa_join_e m_line_join; - bool m_round_cap; -@@ -245,19 +245,19 @@ namespace agg - - switch(dv.flags) - { -- case 0: m_ren.line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break; -- case 1: m_ren.line2(dv.curr, dv.xb2, dv.yb2); break; -- case 2: m_ren.line1(dv.curr, dv.xb1, dv.yb1); break; -- case 3: m_ren.line0(dv.curr); break; -+ case 0: m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break; -+ case 1: m_ren->line2(dv.curr, dv.xb2, dv.yb2); break; -+ case 2: m_ren->line1(dv.curr, dv.xb1, dv.yb1); break; -+ case 3: m_ren->line0(dv.curr); break; - } - - if(m_line_join == outline_round_join && (dv.flags & 2) == 0) - { -- m_ren.pie(dv.curr.x2, dv.curr.y2, -- dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -- dv.curr.y2 - (dv.curr.x2 - dv.curr.x1), -- dv.curr.x2 + (dv.next.y2 - dv.next.y1), -- dv.curr.y2 - (dv.next.x2 - dv.next.x1)); -+ m_ren->pie(dv.curr.x2, dv.curr.y2, -+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1), -+ dv.curr.x2 + (dv.next.y2 - dv.next.y1), -+ dv.curr.y2 - (dv.next.x2 - dv.next.x1)); - } - - dv.x1 = dv.x2; -@@ -406,16 +406,16 @@ namespace agg - line_parameters lp(x1, y1, x2, y2, lprev); - if(m_round_cap) - { -- m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); -+ m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); - } -- m_ren.line3(lp, -- x1 + (y2 - y1), -- y1 - (x2 - x1), -- x2 + (y2 - y1), -- y2 - (x2 - x1)); -+ m_ren->line3(lp, -+ x1 + (y2 - y1), -+ y1 - (x2 - x1), -+ x2 + (y2 - y1), -+ y2 - (x2 - x1)); - if(m_round_cap) - { -- m_ren.semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1)); -+ m_ren->semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1)); - } - } - break; -@@ -440,32 +440,32 @@ namespace agg - - if(m_round_cap) - { -- m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); -+ m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); - } - - if(m_line_join == outline_round_join) - { -- m_ren.line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), -- x2 + (y2 - y1), y2 - (x2 - x1)); -+ m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), -+ x2 + (y2 - y1), y2 - (x2 - x1)); - -- m_ren.pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1), -- x2 + (y3 - y2), y2 - (x3 - x2)); -+ m_ren->pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1), -+ x2 + (y3 - y2), y2 - (x3 - x2)); - -- m_ren.line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2), -- x3 + (y3 - y2), y3 - (x3 - x2)); -+ m_ren->line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2), -+ x3 + (y3 - y2), y3 - (x3 - x2)); - } - else - { - bisectrix(lp1, lp2, &dv.xb1, &dv.yb1); -- m_ren.line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), -- dv.xb1, dv.yb1); -+ m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), -+ dv.xb1, dv.yb1); - -- m_ren.line3(lp2, dv.xb1, dv.yb1, -- x3 + (y3 - y2), y3 - (x3 - x2)); -+ m_ren->line3(lp2, dv.xb1, dv.yb1, -+ x3 + (y3 - y2), y3 - (x3 - x2)); - } - if(m_round_cap) - { -- m_ren.semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2)); -+ m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2)); - } - } - break; -@@ -521,31 +521,31 @@ namespace agg - - if(m_round_cap) - { -- m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); -+ m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); - } - if((dv.flags & 1) == 0) - { - if(m_line_join == outline_round_join) - { -- m_ren.line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), -- x2 + (y2 - y1), y2 - (x2 - x1)); -- m_ren.pie(prev.x2, prev.y2, -- x2 + (y2 - y1), y2 - (x2 - x1), -- dv.curr.x1 + (dv.curr.y2 - dv.curr.y1), -- dv.curr.y1 - (dv.curr.x2 - dv.curr.x1)); -+ m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), -+ x2 + (y2 - y1), y2 - (x2 - x1)); -+ m_ren->pie(prev.x2, prev.y2, -+ x2 + (y2 - y1), y2 - (x2 - x1), -+ dv.curr.x1 + (dv.curr.y2 - dv.curr.y1), -+ dv.curr.y1 - (dv.curr.x2 - dv.curr.x1)); - } - else - { - bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1); -- m_ren.line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), -- dv.xb1, dv.yb1); -+ m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), -+ dv.xb1, dv.yb1); - } - } - else - { -- m_ren.line1(prev, -- x1 + (y2 - y1), -- y1 - (x2 - x1)); -+ m_ren->line1(prev, -+ x1 + (y2 - y1), -+ y1 - (x2 - x1)); - } - if((dv.flags & 2) == 0 && m_line_join != outline_round_join) - { -@@ -558,30 +558,30 @@ namespace agg - { - if(m_line_join == outline_round_join) - { -- m_ren.line3(dv.curr, -- dv.curr.x1 + (dv.curr.y2 - dv.curr.y1), -- dv.curr.y1 - (dv.curr.x2 - dv.curr.x1), -- dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -- dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); -+ m_ren->line3(dv.curr, -+ dv.curr.x1 + (dv.curr.y2 - dv.curr.y1), -+ dv.curr.y1 - (dv.curr.x2 - dv.curr.x1), -+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); - } - else - { -- m_ren.line3(dv.curr, dv.xb1, dv.yb1, -- dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -- dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); -+ m_ren->line3(dv.curr, dv.xb1, dv.yb1, -+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); - } - } - else - { -- m_ren.line2(dv.curr, -- dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -- dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); -+ m_ren->line2(dv.curr, -+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); - } - if(m_round_cap) - { -- m_ren.semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2, -- dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -- dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); -+ m_ren->semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2, -+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), -+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); - } - - } -diff --git a/src/third_party/agg/include/agg_rasterizer_scanline_aa.h b/src/third_party/agg/include/agg_rasterizer_scanline_aa.h -index 20f4c97..39286d7 100644 ---- a/src/third_party/agg/include/agg_rasterizer_scanline_aa.h -+++ b/src/third_party/agg/include/agg_rasterizer_scanline_aa.h -@@ -65,13 +65,6 @@ namespace agg - } - }; - -- //----------------------------------------------------------filling_rule_e -- enum filling_rule_e -- { -- fill_non_zero, -- fill_even_odd -- }; -- - - //==================================================rasterizer_scanline_aa - // Polygon rasterizer that is used to render filled polygons with -@@ -194,8 +187,8 @@ namespace agg - template - void add_path(VertexSource& vs, unsigned path_id=0) - { -- double x; -- double y; -+ double x = 0; -+ double y = 0; - - unsigned cmd; - vs.rewind(path_id); -@@ -364,7 +357,7 @@ namespace agg - template - void rasterizer_scanline_aa::close_polygon() - { -- if(m_auto_close && m_status == status_line_to) -+ if(m_status == status_line_to) - { - m_clipper.line_to(m_outline, m_start_x, m_start_y); - m_status = status_closed; -@@ -376,7 +369,7 @@ namespace agg - void rasterizer_scanline_aa::move_to(int x, int y) - { - if(m_outline.sorted()) reset(); -- if(m_status == status_line_to) close_polygon(); -+ if(m_auto_close) close_polygon(); - m_clipper.move_to(m_start_x = conv_type::downscale(x), - m_start_y = conv_type::downscale(y)); - m_status = status_move_to; -@@ -397,7 +390,7 @@ namespace agg - void rasterizer_scanline_aa::move_to_d(double x, double y) - { - if(m_outline.sorted()) reset(); -- if(m_status == status_line_to) close_polygon(); -+ if(m_auto_close) close_polygon(); - m_clipper.move_to(m_start_x = conv_type::upscale(x), - m_start_y = conv_type::upscale(y)); - m_status = status_move_to; -@@ -422,11 +415,14 @@ namespace agg - move_to_d(x, y); - } - else -+ if(is_vertex(cmd)) - { -- if(is_vertex(cmd)) -- { -- line_to_d(x, y); -- } -+ line_to_d(x, y); -+ } -+ else -+ if(is_close(cmd)) -+ { -+ close_polygon(); - } - } - -@@ -466,7 +462,7 @@ namespace agg - template - AGG_INLINE bool rasterizer_scanline_aa::rewind_scanlines() - { -- close_polygon(); -+ if(m_auto_close) close_polygon(); - m_outline.sort_cells(); - if(m_outline.total_cells() == 0) - { -@@ -481,7 +477,7 @@ namespace agg - template - AGG_INLINE bool rasterizer_scanline_aa::navigate_scanline(int y) - { -- close_polygon(); -+ if(m_auto_close) close_polygon(); - m_outline.sort_cells(); - if(m_outline.total_cells() == 0 || - y < m_outline.min_y() || -@@ -493,31 +489,6 @@ namespace agg - return true; - } - -- //------------------------------------------------------scanline_hit_test -- class scanline_hit_test -- { -- public: -- scanline_hit_test(int x) : m_x(x), m_hit(false) {} -- -- void reset_spans() {} -- void finalize(int) {} -- void add_cell(int x, int) -- { -- if(m_x == x) m_hit = true; -- } -- void add_span(int x, int len, int) -- { -- if(m_x >= x && m_x < x+len) m_hit = true; -- } -- unsigned num_spans() const { return 1; } -- bool hit() const { return m_hit; } -- -- private: -- int m_x; -- bool m_hit; -- }; -- -- - //------------------------------------------------------------------------ - template - bool rasterizer_scanline_aa::hit_test(int tx, int ty) -diff --git a/src/third_party/agg/include/agg_renderer_base.h b/src/third_party/agg/include/agg_renderer_base.h -index 19fd6de..2dc3aa1 100644 ---- a/src/third_party/agg/include/agg_renderer_base.h -+++ b/src/third_party/agg/include/agg_renderer_base.h -@@ -132,7 +132,19 @@ namespace agg - } - } - } -- -+ -+ //-------------------------------------------------------------------- -+ void fill(const color_type& c) -+ { -+ unsigned y; -+ if(width()) -+ { -+ for(y = 0; y < height(); y++) -+ { -+ m_ren->blend_hline(0, y, width(), c, cover_mask); -+ } -+ } -+ } - - //-------------------------------------------------------------------- - void copy_pixel(int x, int y, const color_type& c) -@@ -205,6 +217,7 @@ namespace agg - - m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover); - } -+ - - //-------------------------------------------------------------------- - void blend_vline(int x, int y1, int y2, -@@ -280,6 +293,29 @@ namespace agg - } - m_ren->blend_solid_hspan(x, y, len, c, covers); - } -+ -+ //-------------------------------------------------------------------- -+ void blend_solid_hspan_subpix(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 -= 3 * (xmin() - x); -+ if(len <= 0) return; -+ covers += 3 * (xmin() - x); -+ x = xmin(); -+ } -+ if(x + len / 3 > xmax()) -+ { -+ len = 3 * (xmax() - x + 1); -+ if(len <= 0) return; -+ } -+ m_ren->blend_solid_hspan_subpix(x, y, len, c, covers); -+ } - - //-------------------------------------------------------------------- - void blend_solid_vspan(int x, int y, int len, -@@ -327,6 +363,30 @@ namespace agg - m_ren->copy_color_hspan(x, y, len, colors); - } - -+ -+ //-------------------------------------------------------------------- -+ void copy_color_vspan(int x, int y, int len, const color_type* colors) -+ { -+ if(x > xmax()) return; -+ if(x < xmin()) return; -+ -+ if(y < ymin()) -+ { -+ int d = ymin() - y; -+ len -= d; -+ if(len <= 0) return; -+ colors += d; -+ y = ymin(); -+ } -+ if(y + len > ymax()) -+ { -+ len = ymax() - y + 1; -+ if(len <= 0) return; -+ } -+ m_ren->copy_color_vspan(x, y, len, colors); -+ } -+ -+ - //-------------------------------------------------------------------- - void blend_color_hspan(int x, int y, int len, - const color_type* colors, -diff --git a/src/third_party/agg/include/agg_renderer_markers.h b/src/third_party/agg/include/agg_renderer_markers.h -index 6673e18..820f753 100644 ---- a/src/third_party/agg/include/agg_renderer_markers.h -+++ b/src/third_party/agg/include/agg_renderer_markers.h -@@ -65,8 +65,7 @@ namespace agg - //-------------------------------------------------------------------- - renderer_markers(base_ren_type& rbuf) : - base_type(rbuf) -- { -- } -+ {} - - //-------------------------------------------------------------------- - bool visible(int x, int y, int r) const -diff --git a/src/third_party/agg/include/agg_renderer_mclip.h b/src/third_party/agg/include/agg_renderer_mclip.h -index 2c8eb0f..31da0ed 100644 ---- a/src/third_party/agg/include/agg_renderer_mclip.h -+++ b/src/third_party/agg/include/agg_renderer_mclip.h -@@ -37,11 +37,15 @@ namespace agg - typedef renderer_base base_ren_type; - - //-------------------------------------------------------------------- -- renderer_mclip(pixfmt_type& ren) : -- m_ren(ren), -+ renderer_mclip(pixfmt_type& pixf) : -+ m_ren(pixf), - m_curr_cb(0), - m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax()) -+ {} -+ void attach(pixfmt_type& pixf) - { -+ m_ren.attach(pixf); -+ reset_clipping(true); - } - - //-------------------------------------------------------------------- -diff --git a/src/third_party/agg/include/agg_renderer_outline_aa.h b/src/third_party/agg/include/agg_renderer_outline_aa.h -index b02277a..f9c7674 100644 ---- a/src/third_party/agg/include/agg_renderer_outline_aa.h -+++ b/src/third_party/agg/include/agg_renderer_outline_aa.h -@@ -15,7 +15,7 @@ - #ifndef AGG_RENDERER_OUTLINE_AA_INCLUDED - #define AGG_RENDERER_OUTLINE_AA_INCLUDED - --#include "agg_basics.h" -+#include "agg_array.h" - #include "agg_math.h" - #include "agg_line_aa_basics.h" - #include "agg_dda_line.h" -@@ -1273,13 +1273,8 @@ namespace agg - aa_mask = aa_scale - 1 - }; - -- //--------------------------------------------------------------------- -- ~line_profile_aa() { delete [] m_profile; } -- - //--------------------------------------------------------------------- - line_profile_aa() : -- m_size(0), -- m_profile(0), - m_subpixel_width(0), - m_min_width(1.0), - m_smoother_width(1.0) -@@ -1291,8 +1286,6 @@ namespace agg - //--------------------------------------------------------------------- - template - line_profile_aa(double w, const GammaF& gamma_function) : -- m_size(0), -- m_profile(0), - m_subpixel_width(0), - m_min_width(1.0), - m_smoother_width(1.0) -@@ -1318,7 +1311,7 @@ namespace agg - - void width(double w); - -- unsigned profile_size() const { return m_size; } -+ unsigned profile_size() const { return m_profile.size(); } - int subpixel_width() const { return m_subpixel_width; } - - //--------------------------------------------------------------------- -@@ -1339,12 +1332,11 @@ namespace agg - void set(double center_width, double smoother_width); - - //--------------------------------------------------------------------- -- unsigned m_size; -- value_type* m_profile; -- value_type m_gamma[aa_scale]; -- int m_subpixel_width; -- double m_min_width; -- double m_smoother_width; -+ pod_array m_profile; -+ value_type m_gamma[aa_scale]; -+ int m_subpixel_width; -+ double m_min_width; -+ double m_smoother_width; - }; - - -@@ -1363,8 +1355,8 @@ namespace agg - m_profile(&prof), - m_clip_box(0,0,0,0), - m_clipping(false) -- { -- } -+ {} -+ void attach(base_ren_type& ren) { m_ren = &ren; } - - //--------------------------------------------------------------------- - void color(const color_type& c) { m_color = c; } -@@ -1373,7 +1365,7 @@ namespace agg - //--------------------------------------------------------------------- - void profile(const line_profile_aa& prof) { m_profile = &prof; } - const line_profile_aa& profile() const { return *m_profile; } -- line_profile_aa& profile() { return *m_profile; } -+ line_profile_aa& profile() { return *(line_profile_aa*)m_profile; } - - //--------------------------------------------------------------------- - int subpixel_width() const { return m_profile->subpixel_width(); } -diff --git a/src/third_party/agg/include/agg_renderer_outline_image.h b/src/third_party/agg/include/agg_renderer_outline_image.h -index 8376979..dd48450 100644 ---- a/src/third_party/agg/include/agg_renderer_outline_image.h -+++ b/src/third_party/agg/include/agg_renderer_outline_image.h -@@ -15,6 +15,7 @@ - #ifndef AGG_RENDERER_OUTLINE_IMAGE_INCLUDED - #define AGG_RENDERER_OUTLINE_IMAGE_INCLUDED - -+#include "agg_array.h" - #include "agg_math.h" - #include "agg_line_aa_basics.h" - #include "agg_dda_line.h" -@@ -69,18 +70,12 @@ namespace agg - typedef Filter filter_type; - typedef typename filter_type::color_type color_type; - -- //-------------------------------------------------------------------- -- ~line_image_pattern() -- { -- delete [] m_data; -- } -- - //-------------------------------------------------------------------- - line_image_pattern(const Filter& filter) : - m_filter(&filter), - m_dilation(filter.dilation() + 1), - m_dilation_hr(m_dilation << line_subpixel_shift), -- m_data(0), -+ m_data(), - m_width(0), - m_height(0), - m_width_hr(0), -@@ -96,7 +91,7 @@ namespace agg - m_filter(&filter), - m_dilation(filter.dilation() + 1), - m_dilation_hr(m_dilation << line_subpixel_shift), -- m_data(0), -+ m_data(), - m_width(0), - m_height(0), - m_width_hr(0), -@@ -117,12 +112,11 @@ namespace agg - m_offset_y_hr = m_dilation_hr + m_half_height_hr - line_subpixel_scale/2; - m_half_height_hr += line_subpixel_scale/2; - -- delete [] m_data; -- m_data = new color_type [(m_width + m_dilation * 2) * (m_height + m_dilation * 2)]; -+ m_data.resize((m_width + m_dilation * 2) * (m_height + m_dilation * 2)); - -- m_buf.attach(m_data, m_width + m_dilation * 2, -- m_height + m_dilation * 2, -- m_width + m_dilation * 2); -+ m_buf.attach(&m_data[0], m_width + m_dilation * 2, -+ m_height + m_dilation * 2, -+ m_width + m_dilation * 2); - unsigned x, y; - color_type* d1; - color_type* d2; -@@ -195,7 +189,7 @@ namespace agg - const filter_type* m_filter; - unsigned m_dilation; - int m_dilation_hr; -- color_type* m_data; -+ pod_array m_data; - unsigned m_width; - unsigned m_height; - int m_width_hr; -@@ -829,8 +823,8 @@ namespace agg - m_scale_x(1.0), - m_clip_box(0,0,0,0), - m_clipping(false) -- { -- } -+ {} -+ void attach(base_ren_type& ren) { m_ren = &ren; } - - //--------------------------------------------------------------------- - void pattern(const pattern_type& p) { m_pattern = &p; } -@@ -924,10 +918,6 @@ namespace agg - - fix_degenerate_bisectrix_start(lp, &sx, &sy); - fix_degenerate_bisectrix_end(lp, &ex, &ey); --//sx = lp.x1 + (lp.y2 - lp.y1); --//sy = lp.y1 - (lp.x2 - lp.x1); --//ex = lp.x2 + (lp.y2 - lp.y1); --//ey = lp.y2 - (lp.x2 - lp.x1); - line_interpolator_image li(*this, lp, - sx, sy, - ex, ey, -diff --git a/src/third_party/agg/include/agg_renderer_primitives.h b/src/third_party/agg/include/agg_renderer_primitives.h -index a9d8410..fe4780d 100644 ---- a/src/third_party/agg/include/agg_renderer_primitives.h -+++ b/src/third_party/agg/include/agg_renderer_primitives.h -@@ -41,8 +41,8 @@ namespace agg - m_line_color(), - m_curr_x(0), - m_curr_y(0) -- { -- } -+ {} -+ void attach(base_ren_type& ren) { m_ren = &ren; } - - //-------------------------------------------------------------------- - static int coord(double c) -diff --git a/src/third_party/agg/include/agg_renderer_raster_text.h b/src/third_party/agg/include/agg_renderer_raster_text.h -index d1de298..87b43f9 100644 ---- a/src/third_party/agg/include/agg_renderer_raster_text.h -+++ b/src/third_party/agg/include/agg_renderer_raster_text.h -@@ -34,8 +34,8 @@ namespace agg - renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph) : - m_ren(&ren), - m_glyph(&glyph) -- { -- } -+ {} -+ void attach(ren_type& ren) { m_ren = &ren; } - - //-------------------------------------------------------------------- - void color(const color_type& c) { m_color = c; } -diff --git a/src/third_party/agg/include/agg_renderer_scanline.h b/src/third_party/agg/include/agg_renderer_scanline.h -index 506c635..615fffb 100644 ---- a/src/third_party/agg/include/agg_renderer_scanline.h -+++ b/src/third_party/agg/include/agg_renderer_scanline.h -@@ -52,7 +52,6 @@ namespace agg - } - } - -- - //===============================================render_scanlines_aa_solid - template -@@ -103,7 +102,6 @@ namespace agg - } - } - -- - //==============================================renderer_scanline_aa_solid - template class renderer_scanline_aa_solid - { -@@ -176,8 +174,6 @@ namespace agg - } - } - -- -- - //=====================================================render_scanlines_aa - template -@@ -195,8 +191,6 @@ namespace agg - } - } - -- -- - //====================================================renderer_scanline_aa - template - class renderer_scanline_aa -@@ -244,318 +238,6 @@ namespace agg - - - -- -- -- -- -- -- -- -- -- --/* -- //===================================================renderer_scanline_bin -- template class renderer_scanline_bin -- { -- public: -- typedef BaseRenderer base_ren_type; -- typedef SpanGenerator span_gen_type; -- -- //-------------------------------------------------------------------- -- renderer_scanline_bin() : m_ren(0), m_span_gen(0) {} -- renderer_scanline_bin(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; -- -- if(len < 0) len = -len; -- if(x < xmin) -- { -- len -= xmin - x; -- x = xmin; -- } -- if(len > 0) -- { -- if(x + len > xmax) -- { -- len = xmax - x + 1; -- } -- if(len > 0) -- { -- m_ren->blend_color_hspan_no_clip( -- x, y, len, -- m_span_gen->generate(x, y, len), -- 0); -- } -- } -- if(--num_spans == 0) break; -- ++span; -- } -- } -- } -- while(m_ren->next_clip_box()); -- } -- -- private: -- base_ren_type* m_ren; -- SpanGenerator* m_span_gen; -- }; -- -- -- -- -- -- //================================================renderer_scanline_direct -- template class renderer_scanline_direct -- { -- public: -- typedef BaseRenderer base_ren_type; -- typedef SpanGenerator span_gen_type; -- -- //-------------------------------------------------------------------- -- renderer_scanline_direct() : m_ren(0), m_span_gen(0) {} -- renderer_scanline_direct(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; -- -- if(len < 0) len = -len; -- if(x < xmin) -- { -- len -= xmin - x; -- x = xmin; -- } -- if(len > 0) -- { -- if(x + len > xmax) -- { -- len = xmax - x + 1; -- } -- if(len > 0) -- { -- span_data span = m_ren->span(x, y, len); -- if(span.ptr) -- { -- m_span_gen->generate(span.x, y, span.len, span.ptr); -- } -- } -- } -- if(--num_spans == 0) break; -- ++span; -- } -- } -- } -- while(m_ren->next_clip_box()); -- } -- -- private: -- base_ren_type* m_ren; -- SpanGenerator* m_span_gen; -- }; -- -- -- -- -- -- -- //===============================================renderer_scanline_bin_copy -- template class renderer_scanline_bin_copy -- { -- public: -- typedef BaseRenderer base_ren_type; -- typedef SpanGenerator span_gen_type; -- -- //-------------------------------------------------------------------- -- renderer_scanline_bin_copy() : m_ren(0), m_span_gen(0) {} -- renderer_scanline_bin_copy(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; -- -- if(len < 0) len = -len; -- if(x < xmin) -- { -- len -= xmin - x; -- x = xmin; -- } -- if(len > 0) -- { -- if(x + len > xmax) -- { -- len = xmax - x + 1; -- } -- if(len > 0) -- { -- m_ren->copy_color_hspan_no_clip( -- x, y, len, -- m_span_gen->generate(x, y, len)); -- } -- } -- if(--num_spans == 0) break; -- ++span; -- } -- } -- } -- while(m_ren->next_clip_box()); -- } -- -- private: -- base_ren_type* m_ren; -- SpanGenerator* m_span_gen; -- }; -- -- -- -- //=============================================renderer_scanline_bin_solid -- template class renderer_scanline_bin_solid -- { -- public: -- typedef BaseRenderer base_ren_type; -- typedef typename base_ren_type::color_type color_type; -- -- //-------------------------------------------------------------------- -- renderer_scanline_bin_solid() : m_ren(0) {} -- renderer_scanline_bin_solid(base_ren_type& ren) : -- m_ren(&ren) -- {} -- void attach(base_ren_type& ren) -- { -- m_ren = &ren; -- } -- -- //-------------------------------------------------------------------- -- 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) -- { -- unsigned num_spans = sl.num_spans(); -- typename Scanline::const_iterator span = sl.begin(); -- for(;;) -- { -- m_ren->blend_hline(span->x, -- sl.y(), -- span->x - 1 + ((span->len < 0) ? -- -span->len : -- span->len), -- m_color, -- cover_full); -- if(--num_spans == 0) break; -- ++span; -- } -- } -- -- private: -- base_ren_type* m_ren; -- color_type m_color; -- }; --*/ -- -- -- -- -- -- -- -- -- -- -- -- - //===============================================render_scanline_bin_solid - template - void render_scanline_bin_solid(const Scanline& sl, -@@ -578,7 +260,6 @@ namespace agg - } - } - -- - //==============================================render_scanlines_bin_solid - template -@@ -621,7 +302,6 @@ namespace agg - } - } - -- - //=============================================renderer_scanline_bin_solid - template class renderer_scanline_bin_solid - { -@@ -662,6 +342,92 @@ namespace agg - - - -+ //======================================================render_scanline_bin -+ template -+ void render_scanline_bin(const Scanline& sl, BaseRenderer& ren, -+ SpanAllocator& alloc, SpanGenerator& span_gen) -+ { -+ int y = sl.y(); -+ -+ unsigned num_spans = sl.num_spans(); -+ typename Scanline::const_iterator span = sl.begin(); -+ for(;;) -+ { -+ int x = span->x; -+ int len = span->len; -+ if(len < 0) len = -len; -+ typename BaseRenderer::color_type* colors = alloc.allocate(len); -+ span_gen.generate(colors, x, y, len); -+ ren.blend_color_hspan(x, y, len, colors, 0, cover_full); -+ if(--num_spans == 0) break; -+ ++span; -+ } -+ } -+ -+ //=====================================================render_scanlines_bin -+ template -+ void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, -+ SpanAllocator& alloc, SpanGenerator& span_gen) -+ { -+ if(ras.rewind_scanlines()) -+ { -+ sl.reset(ras.min_x(), ras.max_x()); -+ span_gen.prepare(); -+ while(ras.sweep_scanline(sl)) -+ { -+ render_scanline_bin(sl, ren, alloc, span_gen); -+ } -+ } -+ } -+ -+ //====================================================renderer_scanline_bin -+ template -+ class renderer_scanline_bin -+ { -+ public: -+ typedef BaseRenderer base_ren_type; -+ typedef SpanAllocator alloc_type; -+ typedef SpanGenerator span_gen_type; -+ -+ //-------------------------------------------------------------------- -+ renderer_scanline_bin() : m_ren(0), m_alloc(0), m_span_gen(0) {} -+ renderer_scanline_bin(base_ren_type& ren, -+ alloc_type& alloc, -+ span_gen_type& span_gen) : -+ m_ren(&ren), -+ m_alloc(&alloc), -+ m_span_gen(&span_gen) -+ {} -+ void attach(base_ren_type& ren, -+ alloc_type& alloc, -+ span_gen_type& span_gen) -+ { -+ m_ren = &ren; -+ m_alloc = &alloc; -+ m_span_gen = &span_gen; -+ } -+ -+ //-------------------------------------------------------------------- -+ void prepare() { m_span_gen->prepare(); } -+ -+ //-------------------------------------------------------------------- -+ template void render(const Scanline& sl) -+ { -+ render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen); -+ } -+ -+ private: -+ base_ren_type* m_ren; -+ alloc_type* m_alloc; -+ span_gen_type* m_span_gen; -+ }; -+ -+ -+ -+ -+ - - - -@@ -682,7 +448,6 @@ namespace agg - } - } - -- - //========================================================render_all_paths - template -@@ -707,6 +472,10 @@ namespace agg - - - -+ -+ -+ -+ - //=============================================render_scanlines_compound - templatex - min_x, -- 0, -- span_bin->len * sizeof(color_type)); -+ memset(mix_buffer + sl_start - min_x, -+ 0, -+ sl_len * sizeof(color_type)); - -- if(--num_spans == 0) break; -- ++span_bin; -- } -+ memset(cover_buffer + sl_start - min_x, -+ 0, -+ sl_len * sizeof(cover_type)); - -+ int sl_y = 0x7FFFFFFF; - unsigned i; - for(i = 0; i < num_styles; i++) - { -@@ -804,11 +571,14 @@ namespace agg - - if(ras.sweep_scanline(sl_aa, i)) - { -+ unsigned cover; - color_type* colors; - color_type* cspan; -- typename ScanlineAA::cover_type* covers; -+ cover_type* src_covers; -+ cover_type* dst_covers; - span_aa = sl_aa.begin(); - num_spans = sl_aa.num_spans(); -+ sl_y = sl_aa.y(); - if(solid) - { - // Just solid fill -@@ -818,12 +588,23 @@ namespace agg - color_type c = sh.color(style); - len = span_aa->len; - colors = mix_buffer + span_aa->x - min_x; -- covers = span_aa->covers; -+ src_covers = span_aa->covers; -+ dst_covers = cover_buffer + span_aa->x - min_x; - do - { -- colors->add(c, *covers); -+ cover = *src_covers; -+ if(*dst_covers + cover > cover_full) -+ { -+ cover = cover_full - *dst_covers; -+ } -+ if(cover) -+ { -+ colors->add(c, cover); -+ *dst_covers += cover; -+ } - ++colors; -- ++covers; -+ ++src_covers; -+ ++dst_covers; - } - while(--len); - if(--num_spans == 0) break; -@@ -844,13 +625,24 @@ namespace agg - sl_aa.y(), - len, - style); -- covers = span_aa->covers; -+ src_covers = span_aa->covers; -+ dst_covers = cover_buffer + span_aa->x - min_x; - do - { -- colors->add(*cspan, *covers); -+ cover = *src_covers; -+ if(*dst_covers + cover > cover_full) -+ { -+ cover = cover_full - *dst_covers; -+ } -+ if(cover) -+ { -+ colors->add(*cspan, cover); -+ *dst_covers += cover; -+ } - ++cspan; - ++colors; -- ++covers; -+ ++src_covers; -+ ++dst_covers; - } - while(--len); - if(--num_spans == 0) break; -@@ -859,33 +651,19 @@ namespace agg - } - } - } -- -- // Emit the blended result as a color hspan -- //------------------------- -- span_bin = sl_bin.begin(); -- num_spans = sl_bin.num_spans(); -- for(;;) -- { -- ren.blend_color_hspan(span_bin->x, -- sl_bin.y(), -- span_bin->len, -- mix_buffer + span_bin->x - min_x, -- 0, -- cover_full); -- if(--num_spans == 0) break; -- ++span_bin; -- } -- -- } -- } -- } -- } -+ ren.blend_color_hspan(sl_start, -+ sl_y, -+ sl_len, -+ mix_buffer + sl_start - min_x, -+ 0, -+ cover_full); -+ } //if(sl_len) -+ } //if(num_styles == 1) ... else -+ } //while((num_styles = ras.sweep_styles()) > 0) -+ } //if(ras.rewind_scanlines()) - } - - -- -- -- - } - - #endif -diff --git a/src/third_party/agg/include/agg_rendering_buffer.h b/src/third_party/agg/include/agg_rendering_buffer.h -index 399c554..54268bd 100644 ---- a/src/third_party/agg/include/agg_rendering_buffer.h -+++ b/src/third_party/agg/include/agg_rendering_buffer.h -@@ -20,7 +20,7 @@ - #ifndef AGG_RENDERING_BUFFER_INCLUDED - #define AGG_RENDERING_BUFFER_INCLUDED - --#include "agg_basics.h" -+#include "agg_array.h" - - namespace agg - { -@@ -39,31 +39,23 @@ namespace agg - x1(x1_), x2(x2_), ptr(ptr_) {} - }; - -- //------------------------------------------------------------------- -- ~row_ptr_cache() -- { -- delete [] m_rows; -- } -- - //------------------------------------------------------------------- - row_ptr_cache() : - m_buf(0), -- m_rows(0), -+ m_rows(), - m_width(0), - m_height(0), -- m_stride(0), -- m_max_height(0) -+ m_stride(0) - { - } - - //-------------------------------------------------------------------- - row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) : - m_buf(0), -- m_rows(0), -+ m_rows(), - m_width(0), - m_height(0), -- m_stride(0), -- m_max_height(0) -+ m_stride(0) - { - attach(buf, width, height, stride); - } -@@ -75,20 +67,19 @@ namespace agg - m_width = width; - m_height = height; - m_stride = stride; -- if(height > m_max_height) -+ if(height > m_rows.size()) - { -- delete [] m_rows; -- m_rows = new T* [m_max_height = height]; -+ m_rows.resize(height); - } - - T* row_ptr = m_buf; - - if(stride < 0) - { -- row_ptr = m_buf - (height - 1) * stride; -+ row_ptr = m_buf - int(height - 1) * stride; - } - -- T** rows = m_rows; -+ T** rows = &m_rows[0]; - - while(height--) - { -@@ -115,7 +106,7 @@ namespace agg - row_data row (int y) const { return row_data(0, m_width-1, m_rows[y]); } - - //-------------------------------------------------------------------- -- T const* const* rows() const { return m_rows; } -+ T const* const* rows() const { return &m_rows[0]; } - - //-------------------------------------------------------------------- - template -@@ -154,21 +145,13 @@ namespace agg - } - } - -- -- private: -- //-------------------------------------------------------------------- -- // Prohibit copying -- row_ptr_cache(const row_ptr_cache&); -- const row_ptr_cache& operator = (const row_ptr_cache&); -- - private: - //-------------------------------------------------------------------- -- T* m_buf; // Pointer to renrdering buffer -- T** m_rows; // Pointers to each row of the buffer -- unsigned m_width; // Width in pixels -- unsigned m_height; // Height in pixels -- int m_stride; // Number of bytes per row. Can be < 0 -- unsigned m_max_height; // The maximal height (currently allocated) -+ T* m_buf; // Pointer to renrdering buffer -+ pod_array m_rows; // Pointers to each row of the buffer -+ unsigned m_width; // Width in pixels -+ unsigned m_height; // Height in pixels -+ int m_stride; // Number of bytes per row. Can be < 0 - }; - - -diff --git a/src/third_party/agg/include/agg_rendering_buffer_dynarow.h b/src/third_party/agg/include/agg_rendering_buffer_dynarow.h -index f7a9134..7ae61c3 100644 ---- a/src/third_party/agg/include/agg_rendering_buffer_dynarow.h -+++ b/src/third_party/agg/include/agg_rendering_buffer_dynarow.h -@@ -20,8 +20,7 @@ - #ifndef AGG_RENDERING_BUFFER_DYNAROW_INCLUDED - #define AGG_RENDERING_BUFFER_DYNAROW_INCLUDED - --#include --#include "agg_basics.h" -+#include "agg_array.h" - - namespace agg - { -@@ -51,9 +50,10 @@ namespace agg - - //------------------------------------------------------------------- - rendering_buffer_dynarow() : -- m_rows(0), -+ m_rows(), - m_width(0), -- m_height(0) -+ m_height(0), -+ m_byte_width(0) - { - } - -@@ -61,12 +61,12 @@ namespace agg - //-------------------------------------------------------------------- - rendering_buffer_dynarow(unsigned width, unsigned height, - unsigned byte_width) : -- m_rows(new row_data[height]), -+ m_rows(height), - m_width(width), - m_height(height), - m_byte_width(byte_width) - { -- memset(m_rows, 0, sizeof(row_data) * height); -+ memset(&m_rows[0], 0, sizeof(row_data) * height); - } - - // Allocate and clear the buffer -@@ -74,16 +74,17 @@ namespace agg - void init(unsigned width, unsigned height, unsigned byte_width) - { - unsigned i; -- for(i = 0; i < m_height; ++i) delete [] (int8u*)m_rows[i].ptr; -- delete [] m_rows; -- m_rows = 0; -+ for(i = 0; i < m_height; ++i) -+ { -+ pod_allocator::deallocate((int8u*)m_rows[i].ptr, m_byte_width); -+ } - if(width && height) - { - m_width = width; - m_height = height; - m_byte_width = byte_width; -- m_rows = new row_data[height]; -- memset(m_rows, 0, sizeof(row_data) * height); -+ m_rows.resize(height); -+ memset(&m_rows[0], 0, sizeof(row_data) * height); - } - } - -@@ -97,7 +98,7 @@ namespace agg - //-------------------------------------------------------------------- - int8u* row_ptr(int x, int y, unsigned len) - { -- row_data* r = m_rows + y; -+ row_data* r = &m_rows[y]; - int x2 = x + len - 1; - if(r->ptr) - { -@@ -106,7 +107,7 @@ namespace agg - } - else - { -- int8u* p = new int8u [m_byte_width]; -+ int8u* p = pod_allocator::allocate(m_byte_width); - r->ptr = p; - r->x1 = x; - r->x2 = x2; -@@ -128,10 +129,10 @@ namespace agg - - private: - //-------------------------------------------------------------------- -- row_data* m_rows; // Pointers to each row of the buffer -- unsigned m_width; // Width in pixels -- unsigned m_height; // Height in pixels -- unsigned m_byte_width; // Width in bytes -+ pod_array m_rows; // Pointers to each row of the buffer -+ unsigned m_width; // Width in pixels -+ unsigned m_height; // Height in pixels -+ unsigned m_byte_width; // Width in bytes - }; - - -diff --git a/src/third_party/agg/include/agg_scanline_bin.h b/src/third_party/agg/include/agg_scanline_bin.h -index e0584d0..660292b 100644 ---- a/src/third_party/agg/include/agg_scanline_bin.h -+++ b/src/third_party/agg/include/agg_scanline_bin.h -@@ -54,15 +54,9 @@ namespace agg - typedef const span* const_iterator; - - //-------------------------------------------------------------------- -- ~scanline_bin() -- { -- delete [] m_spans; -- } -- - scanline_bin() : -- m_max_len(0), - m_last_x(0x7FFFFFF0), -- m_spans(0), -+ m_spans(), - m_cur_span(0) - { - } -@@ -71,14 +65,12 @@ namespace agg - void reset(int min_x, int max_x) - { - unsigned max_len = max_x - min_x + 3; -- if(max_len > m_max_len) -+ if(max_len > m_spans.size()) - { -- delete [] m_spans; -- m_spans = new span [max_len]; -- m_max_len = max_len; -+ m_spans.resize(max_len); - } - m_last_x = 0x7FFFFFF0; -- m_cur_span = m_spans; -+ m_cur_span = &m_spans[0]; - } - - //-------------------------------------------------------------------- -@@ -129,23 +121,22 @@ namespace agg - void reset_spans() - { - m_last_x = 0x7FFFFFF0; -- m_cur_span = m_spans; -+ m_cur_span = &m_spans[0]; - } - - //-------------------------------------------------------------------- - int y() const { return m_y; } -- unsigned num_spans() const { return unsigned(m_cur_span - m_spans); } -- const_iterator begin() const { return m_spans + 1; } -+ unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } -+ const_iterator begin() const { return &m_spans[1]; } - - private: - scanline_bin(const scanline_bin&); - const scanline_bin operator = (const scanline_bin&); - -- unsigned m_max_len; -- int m_last_x; -- int m_y; -- span* m_spans; -- span* m_cur_span; -+ int m_last_x; -+ int m_y; -+ pod_array m_spans; -+ span* m_cur_span; - }; - - -diff --git a/src/third_party/agg/include/agg_scanline_boolean_algebra.h b/src/third_party/agg/include/agg_scanline_boolean_algebra.h -index ad359e6..bc2e9c9 100644 ---- a/src/third_party/agg/include/agg_scanline_boolean_algebra.h -+++ b/src/third_party/agg/include/agg_scanline_boolean_algebra.h -@@ -850,8 +850,8 @@ namespace agg - unsigned num1 = sl1.num_spans(); - unsigned num2 = sl2.num_spans(); - -- typename Scanline1::const_iterator span1; -- typename Scanline2::const_iterator span2; -+ typename Scanline1::const_iterator span1;// = sl1.begin(); -+ typename Scanline2::const_iterator span2;// = sl2.begin(); - - enum invalidation_e - { -@@ -1046,7 +1046,11 @@ namespace agg - - // Calculate the union of the bounding boxes - //----------------- -- rect_i ur = unite_rectangles(r1, r2); -+ rect_i ur(1,1,0,0); -+ if(flag1 && flag2) ur = unite_rectangles(r1, r2); -+ else if(flag1) ur = r1; -+ else if(flag2) ur = r2; -+ - if(!ur.is_valid()) return; - - ren.prepare(); -@@ -1176,7 +1180,7 @@ namespace agg - ren.prepare(); - - // A fake span2 processor -- sbool_add_span_empty add_span2; -+ sbool_add_span_empty add_span2; - - // The main loop - // Here we synchronize the scanlines with -diff --git a/src/third_party/agg/include/agg_scanline_p.h b/src/third_party/agg/include/agg_scanline_p.h -index e93bbd5..1d1cbe7 100644 ---- a/src/third_party/agg/include/agg_scanline_p.h -+++ b/src/third_party/agg/include/agg_scanline_p.h -@@ -57,19 +57,11 @@ namespace agg - typedef span* iterator; - typedef const span* const_iterator; - -- //-------------------------------------------------------------------- -- ~scanline_p8() -- { -- delete [] m_spans; -- delete [] m_covers; -- } -- - scanline_p8() : -- m_max_len(0), - m_last_x(0x7FFFFFF0), -- m_covers(0), -+ m_covers(), - m_cover_ptr(0), -- m_spans(0), -+ m_spans(), - m_cur_span(0) - { - } -@@ -78,17 +70,14 @@ namespace agg - void reset(int min_x, int max_x) - { - unsigned max_len = max_x - min_x + 3; -- if(max_len > m_max_len) -+ if(max_len > m_spans.size()) - { -- delete [] m_spans; -- delete [] m_covers; -- m_covers = new cover_type [max_len]; -- m_spans = new span [max_len]; -- m_max_len = max_len; -+ m_spans.resize(max_len); -+ m_covers.resize(max_len); - } - m_last_x = 0x7FFFFFF0; -- m_cover_ptr = m_covers; -- m_cur_span = m_spans; -+ m_cover_ptr = &m_covers[0]; -+ m_cur_span = &m_spans[0]; - m_cur_span->len = 0; - } - -@@ -160,27 +149,26 @@ namespace agg - void reset_spans() - { - m_last_x = 0x7FFFFFF0; -- m_cover_ptr = m_covers; -- m_cur_span = m_spans; -+ m_cover_ptr = &m_covers[0]; -+ m_cur_span = &m_spans[0]; - m_cur_span->len = 0; - } - - //-------------------------------------------------------------------- - int y() const { return m_y; } -- unsigned num_spans() const { return unsigned(m_cur_span - m_spans); } -- const_iterator begin() const { return m_spans + 1; } -+ unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } -+ const_iterator begin() const { return &m_spans[1]; } - - private: - scanline_p8(const self_type&); - const self_type& operator = (const self_type&); - -- unsigned m_max_len; -- int m_last_x; -- int m_y; -- cover_type* m_covers; -- cover_type* m_cover_ptr; -- span* m_spans; -- span* m_cur_span; -+ int m_last_x; -+ int m_y; -+ pod_array m_covers; -+ cover_type* m_cover_ptr; -+ pod_array m_spans; -+ span* m_cur_span; - }; - - -@@ -231,15 +219,10 @@ namespace agg - }; - - //-------------------------------------------------------------------- -- ~scanline32_p8() -- { -- delete [] m_covers; -- } -- - scanline32_p8() : - m_max_len(0), - m_last_x(0x7FFFFFF0), -- m_covers(0), -+ m_covers(), - m_cover_ptr(0) - { - } -@@ -248,14 +231,12 @@ namespace agg - void reset(int min_x, int max_x) - { - unsigned max_len = max_x - min_x + 3; -- if(max_len > m_max_len) -+ if(max_len > m_covers.size()) - { -- delete [] m_covers; -- m_covers = new cover_type[max_len]; -- m_max_len = max_len; -+ m_covers.resize(max_len); - } - m_last_x = 0x7FFFFFF0; -- m_cover_ptr = m_covers; -+ m_cover_ptr = &m_covers[0]; - m_spans.remove_all(); - } - -@@ -319,7 +300,7 @@ namespace agg - void reset_spans() - { - m_last_x = 0x7FFFFFF0; -- m_cover_ptr = m_covers; -+ m_cover_ptr = &m_covers[0]; - m_spans.remove_all(); - } - -@@ -332,12 +313,12 @@ namespace agg - scanline32_p8(const self_type&); - const self_type& operator = (const self_type&); - -- unsigned m_max_len; -- int m_last_x; -- int m_y; -- cover_type* m_covers; -- cover_type* m_cover_ptr; -- span_array_type m_spans; -+ unsigned m_max_len; -+ int m_last_x; -+ int m_y; -+ pod_array m_covers; -+ cover_type* m_cover_ptr; -+ span_array_type m_spans; - }; - - -diff --git a/src/third_party/agg/include/agg_scanline_storage_aa.h b/src/third_party/agg/include/agg_scanline_storage_aa.h -index 4ea187e..be452a8 100644 ---- a/src/third_party/agg/include/agg_scanline_storage_aa.h -+++ b/src/third_party/agg/include/agg_scanline_storage_aa.h -@@ -83,7 +83,8 @@ namespace agg - int i; - for(i = m_extra_storage.size()-1; i >= 0; --i) - { -- delete [] m_extra_storage[(unsigned)i].ptr; -+ pod_allocator::deallocate(m_extra_storage[i].ptr, -+ m_extra_storage[i].len); - } - m_extra_storage.remove_all(); - m_cells.remove_all(); -@@ -101,7 +102,7 @@ namespace agg - } - extra_span s; - s.len = num_cells; -- s.ptr = new T [num_cells]; -+ s.ptr = pod_allocator::allocate(num_cells); - memcpy(s.ptr, cells, sizeof(T) * num_cells); - m_extra_storage.add(s); - return -int(m_extra_storage.size()); -@@ -142,7 +143,7 @@ namespace agg - const extra_span& src = v.m_extra_storage[i]; - extra_span dst; - dst.len = src.len; -- dst.ptr = new T [dst.len]; -+ dst.ptr = pod_allocator::allocate(dst.len); - memcpy(dst.ptr, src.ptr, dst.len * sizeof(T)); - m_extra_storage.add(dst); - } -@@ -196,6 +197,7 @@ namespace agg - const T* covers; - }; - -+ const_iterator() : m_storage(0) {} - const_iterator(const embedded_scanline& sl) : - m_storage(sl.m_storage), - m_span_idx(sl.m_scanline.start_span) -@@ -554,6 +556,7 @@ namespace agg - const T* covers; - }; - -+ const_iterator() : m_ptr(0) {} - const_iterator(const embedded_scanline& sl) : - m_ptr(sl.m_ptr), - m_dx(sl.m_dx) -@@ -721,9 +724,8 @@ namespace agg - m_min_y = read_int32() + m_dy; - m_max_x = read_int32() + m_dx; - m_max_y = read_int32() + m_dy; -- return true; - } -- return false; -+ return m_ptr < m_end; - } - - //-------------------------------------------------------------------- -diff --git a/src/third_party/agg/include/agg_scanline_storage_bin.h b/src/third_party/agg/include/agg_scanline_storage_bin.h -index 07ea2ee..d760016 100644 ---- a/src/third_party/agg/include/agg_scanline_storage_bin.h -+++ b/src/third_party/agg/include/agg_scanline_storage_bin.h -@@ -63,6 +63,7 @@ namespace agg - class const_iterator - { - public: -+ const_iterator() : m_storage(0) {} - const_iterator(const embedded_scanline& sl) : - m_storage(sl.m_storage), - m_span_idx(sl.m_scanline.start_span) -@@ -360,6 +361,7 @@ namespace agg - int32 len; - }; - -+ const_iterator() : m_ptr(0) {} - const_iterator(const embedded_scanline& sl) : - m_ptr(sl.m_ptr), - m_dx(sl.m_dx) -@@ -503,9 +505,8 @@ namespace agg - m_min_y = read_int32() + m_dy; - m_max_x = read_int32() + m_dx; - m_max_y = read_int32() + m_dy; -- return true; - } -- return false; -+ return m_ptr < m_end; - } - - //-------------------------------------------------------------------- -diff --git a/src/third_party/agg/include/agg_scanline_u.h b/src/third_party/agg/include/agg_scanline_u.h -index 1151306..630eb9d 100644 ---- a/src/third_party/agg/include/agg_scanline_u.h -+++ b/src/third_party/agg/include/agg_scanline_u.h -@@ -125,18 +125,9 @@ namespace agg - typedef const span* const_iterator; - - //-------------------------------------------------------------------- -- ~scanline_u8() -- { -- delete [] m_spans; -- delete [] m_covers; -- } -- - scanline_u8() : - m_min_x(0), -- m_max_len(0), - m_last_x(0x7FFFFFF0), -- m_covers(0), -- m_spans(0), - m_cur_span(0) - {} - -@@ -144,17 +135,14 @@ namespace agg - void reset(int min_x, int max_x) - { - unsigned max_len = max_x - min_x + 2; -- if(max_len > m_max_len) -+ if(max_len > m_spans.size()) - { -- delete [] m_spans; -- delete [] m_covers; -- m_covers = new cover_type [max_len]; -- m_spans = new span [max_len]; -- m_max_len = max_len; -+ m_spans.resize(max_len); -+ m_covers.resize(max_len); - } -- m_last_x = 0x7FFFFFF0; -- m_min_x = min_x; -- m_cur_span = m_spans; -+ m_last_x = 0x7FFFFFF0; -+ m_min_x = min_x; -+ m_cur_span = &m_spans[0]; - } - - //-------------------------------------------------------------------- -@@ -171,7 +159,7 @@ namespace agg - 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_cur_span->covers = &m_covers[x]; - } - m_last_x = x; - } -@@ -180,7 +168,7 @@ namespace agg - void add_cells(int x, unsigned len, const cover_type* covers) - { - x -= m_min_x; -- memcpy(m_covers + x, covers, len * sizeof(cover_type)); -+ memcpy(&m_covers[x], covers, len * sizeof(cover_type)); - if(x == m_last_x+1) - { - m_cur_span->len += (coord_type)len; -@@ -190,7 +178,7 @@ namespace agg - 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_cur_span->covers = &m_covers[x]; - } - m_last_x = x + len - 1; - } -@@ -199,7 +187,7 @@ namespace agg - void add_span(int x, unsigned len, unsigned cover) - { - x -= m_min_x; -- memset(m_covers + x, cover, len); -+ memset(&m_covers[x], cover, len); - if(x == m_last_x+1) - { - m_cur_span->len += (coord_type)len; -@@ -209,7 +197,7 @@ namespace agg - 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_cur_span->covers = &m_covers[x]; - } - m_last_x = x + len - 1; - } -@@ -224,27 +212,26 @@ namespace agg - void reset_spans() - { - m_last_x = 0x7FFFFFF0; -- m_cur_span = m_spans; -+ m_cur_span = &m_spans[0]; - } - - //-------------------------------------------------------------------- - int y() const { return m_y; } -- unsigned num_spans() const { return unsigned(m_cur_span - m_spans); } -- const_iterator begin() const { return m_spans + 1; } -- iterator begin() { return m_spans + 1; } -+ unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } -+ const_iterator begin() const { return &m_spans[1]; } -+ iterator begin() { return &m_spans[1]; } - - private: - scanline_u8(const self_type&); - const self_type& operator = (const self_type&); - - private: -- int m_min_x; -- unsigned m_max_len; -- int m_last_x; -- int m_y; -- cover_type* m_covers; -- span* m_spans; -- span* m_cur_span; -+ int m_min_x; -+ int m_last_x; -+ int m_y; -+ pod_array m_covers; -+ pod_array m_spans; -+ span* m_cur_span; - }; - - -@@ -265,7 +252,7 @@ namespace agg - typedef base_type::coord_type coord_type; - - scanline_u8_am() : base_type(), m_alpha_mask(0) {} -- scanline_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {} -+ scanline_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} - - //-------------------------------------------------------------------- - void finalize(int span_y) -@@ -288,7 +275,7 @@ namespace agg - } - - private: -- const AlphaMask* m_alpha_mask; -+ AlphaMask* m_alpha_mask; - }; - - -@@ -357,27 +344,19 @@ namespace agg - - - //-------------------------------------------------------------------- -- ~scanline32_u8() -- { -- delete [] m_covers; -- } -- - scanline32_u8() : - m_min_x(0), -- m_max_len(0), - m_last_x(0x7FFFFFF0), -- m_covers(0) -+ m_covers() - {} - - //-------------------------------------------------------------------- - void reset(int min_x, int max_x) - { - unsigned max_len = max_x - min_x + 2; -- if(max_len > m_max_len) -+ if(max_len > m_covers.size()) - { -- delete [] m_covers; -- m_covers = new cover_type [max_len]; -- m_max_len = max_len; -+ m_covers.resize(max_len); - } - m_last_x = 0x7FFFFFF0; - m_min_x = min_x; -@@ -395,7 +374,7 @@ namespace agg - } - else - { -- m_spans.add(span(coord_type(x + m_min_x), 1, m_covers + x)); -+ m_spans.add(span(coord_type(x + m_min_x), 1, &m_covers[x])); - } - m_last_x = x; - } -@@ -404,14 +383,16 @@ namespace agg - void add_cells(int x, unsigned len, const cover_type* covers) - { - x -= m_min_x; -- memcpy(m_covers + x, covers, len * sizeof(cover_type)); -+ memcpy(&m_covers[x], covers, len * sizeof(cover_type)); - if(x == m_last_x+1) - { - m_spans.last().len += coord_type(len); - } - else - { -- m_spans.add(span(coord_type(x + m_min_x), coord_type(len), m_covers + x)); -+ m_spans.add(span(coord_type(x + m_min_x), -+ coord_type(len), -+ &m_covers[x])); - } - m_last_x = x + len - 1; - } -@@ -420,14 +401,16 @@ namespace agg - void add_span(int x, unsigned len, unsigned cover) - { - x -= m_min_x; -- memset(m_covers + x, cover, len); -+ memset(&m_covers[x], cover, len); - if(x == m_last_x+1) - { - m_spans.last().len += coord_type(len); - } - else - { -- m_spans.add(span(coord_type(x + m_min_x), coord_type(len), m_covers + x)); -+ m_spans.add(span(coord_type(x + m_min_x), -+ coord_type(len), -+ &m_covers[x])); - } - m_last_x = x + len - 1; - } -@@ -456,12 +439,11 @@ namespace agg - 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_array_type m_spans; -+ int m_min_x; -+ int m_last_x; -+ int m_y; -+ pod_array m_covers; -+ span_array_type m_spans; - }; - - -@@ -476,14 +458,14 @@ namespace agg - class scanline32_u8_am : public scanline32_u8 - { - public: -- typedef scanline_u8 base_type; -+ typedef scanline32_u8 base_type; - typedef AlphaMask alpha_mask_type; - typedef base_type::cover_type cover_type; - typedef base_type::coord_type coord_type; - - - scanline32_u8_am() : base_type(), m_alpha_mask(0) {} -- scanline32_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {} -+ scanline32_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} - - //-------------------------------------------------------------------- - void finalize(int span_y) -@@ -506,7 +488,7 @@ namespace agg - } - - private: -- const AlphaMask* m_alpha_mask; -+ AlphaMask* m_alpha_mask; - }; - - -diff --git a/src/third_party/agg/include/agg_span_allocator.h b/src/third_party/agg/include/agg_span_allocator.h -index 4cbc3cc..201b69b 100644 ---- a/src/third_party/agg/include/agg_span_allocator.h -+++ b/src/third_party/agg/include/agg_span_allocator.h -@@ -16,7 +16,7 @@ - #ifndef AGG_SPAN_ALLOCATOR_INCLUDED - #define AGG_SPAN_ALLOCATOR_INCLUDED - --#include "agg_basics.h" -+#include "agg_array.h" - - namespace agg - { -@@ -26,45 +26,25 @@ namespace agg - public: - typedef ColorT color_type; - -- //-------------------------------------------------------------------- -- ~span_allocator() -- { -- delete [] m_span; -- } -- -- //-------------------------------------------------------------------- -- span_allocator() : -- m_max_span_len(0), -- m_span(0) -- { -- } -- - //-------------------------------------------------------------------- - AGG_INLINE color_type* allocate(unsigned span_len) - { -- if(span_len > m_max_span_len) -+ if(span_len > m_span.size()) - { - // To reduce the number of reallocs we align the - // span_len to 256 color elements. - // Well, I just like this number and it looks reasonable. - //----------------------- -- delete [] m_span; -- span_len = ((span_len + 255) >> 8) << 8; -- m_span = new color_type[m_max_span_len = span_len]; -+ m_span.resize(((span_len + 255) >> 8) << 8); - } -- return m_span; -+ return &m_span[0]; - } - -- AGG_INLINE color_type* span() { return m_span; } -- AGG_INLINE unsigned max_span_len() const { return m_max_span_len; } -+ AGG_INLINE color_type* span() { return &m_span[0]; } -+ AGG_INLINE unsigned max_span_len() const { return m_span.size(); } - - private: -- //-------------------------------------------------------------------- -- span_allocator(const span_allocator&); -- const span_allocator& operator = (const span_allocator&); -- -- unsigned m_max_span_len; -- color_type* m_span; -+ pod_array m_span; - }; - } - -diff --git a/src/third_party/agg/include/agg_span_converter.h b/src/third_party/agg/include/agg_span_converter.h -index 27b78e1..91d0f87 100644 ---- a/src/third_party/agg/include/agg_span_converter.h -+++ b/src/third_party/agg/include/agg_span_converter.h -@@ -29,6 +29,9 @@ namespace agg - span_converter(SpanGenerator& span_gen, SpanConverter& span_cnv) : - m_span_gen(&span_gen), m_span_cnv(&span_cnv) {} - -+ void attach_generator(SpanGenerator& span_gen) { m_span_gen = &span_gen; } -+ void attach_converter(SpanConverter& span_cnv) { m_span_cnv = &span_cnv; } -+ - //-------------------------------------------------------------------- - void prepare() - { -diff --git a/src/third_party/agg/include/agg_span_gouraud_gray.h b/src/third_party/agg/include/agg_span_gouraud_gray.h -index 347b5c8..d5fc39d 100644 ---- a/src/third_party/agg/include/agg_span_gouraud_gray.h -+++ b/src/third_party/agg/include/agg_span_gouraud_gray.h -@@ -108,9 +108,9 @@ namespace agg - - m_y2 = int(coord[1].y); - -- m_swap = calc_point_location(coord[0].x, coord[0].y, -- coord[2].x, coord[2].y, -- coord[1].x, coord[1].y) < 0.0; -+ m_swap = cross_product(coord[0].x, coord[0].y, -+ coord[2].x, coord[2].y, -+ coord[1].x, coord[1].y) < 0.0; - - m_c1.init(coord[0], coord[2]); - m_c2.init(coord[0], coord[1]); -diff --git a/src/third_party/agg/include/agg_span_gouraud_rgba.h b/src/third_party/agg/include/agg_span_gouraud_rgba.h -index 7c54833..89192d2 100644 ---- a/src/third_party/agg/include/agg_span_gouraud_rgba.h -+++ b/src/third_party/agg/include/agg_span_gouraud_rgba.h -@@ -120,9 +120,9 @@ namespace agg - - m_y2 = int(coord[1].y); - -- m_swap = calc_point_location(coord[0].x, coord[0].y, -- coord[2].x, coord[2].y, -- coord[1].x, coord[1].y) < 0.0; -+ m_swap = cross_product(coord[0].x, coord[0].y, -+ coord[2].x, coord[2].y, -+ coord[1].x, coord[1].y) < 0.0; - - m_rgba1.init(coord[0], coord[2]); - m_rgba2.init(coord[0], coord[1]); -diff --git a/src/third_party/agg/include/agg_span_image_filter.h b/src/third_party/agg/include/agg_span_image_filter.h -index 4832917..47e2f44 100644 ---- a/src/third_party/agg/include/agg_span_image_filter.h -+++ b/src/third_party/agg/include/agg_span_image_filter.h -@@ -46,6 +46,7 @@ namespace agg - m_dx_int(image_subpixel_scale / 2), - m_dy_int(image_subpixel_scale / 2) - {} -+ void attach(source_type& v) { m_src = &v; } - - //-------------------------------------------------------------------- - source_type& source() { return *m_src; } -@@ -57,7 +58,6 @@ namespace agg - double filter_dy_dbl() const { return m_dy_dbl; } - - //-------------------------------------------------------------------- -- void set_source(source_type& v) { m_src = &v; } - void interpolator(interpolator_type& v) { m_interpolator = &v; } - void filter(const image_filter_lut& v) { m_filter = &v; } - void filter_offset(double dx, double dy) -@@ -136,33 +136,29 @@ namespace agg - - base_type::interpolator().transformer().scaling_abs(&scale_x, &scale_y); - -- m_rx = image_subpixel_scale; -- m_ry = image_subpixel_scale; -- m_rx_inv = image_subpixel_scale; -- m_ry_inv = image_subpixel_scale; -- -- scale_x *= m_blur_x; -- scale_y *= m_blur_y; -- - if(scale_x * scale_y > m_scale_limit) - { - scale_x = scale_x * m_scale_limit / (scale_x * scale_y); - scale_y = scale_y * m_scale_limit / (scale_x * scale_y); - } - -- if(scale_x > 1.0001) -- { -- if(scale_x > m_scale_limit) scale_x = m_scale_limit; -- m_rx = uround( scale_x * double(image_subpixel_scale)); -- m_rx_inv = uround(1.0/scale_x * double(image_subpixel_scale)); -- } -+ if(scale_x < 1) scale_x = 1; -+ if(scale_y < 1) scale_y = 1; - -- if(scale_y > 1.0001) -- { -- if(scale_y > m_scale_limit) scale_y = m_scale_limit; -- m_ry = uround( scale_y * double(image_subpixel_scale)); -- m_ry_inv = uround(1.0/scale_y * double(image_subpixel_scale)); -- } -+ if(scale_x > m_scale_limit) scale_x = m_scale_limit; -+ if(scale_y > m_scale_limit) scale_y = m_scale_limit; -+ -+ scale_x *= m_blur_x; -+ scale_y *= m_blur_y; -+ -+ if(scale_x < 1) scale_x = 1; -+ if(scale_y < 1) scale_y = 1; -+ -+ m_rx = uround( scale_x * double(image_subpixel_scale)); -+ m_rx_inv = uround(1.0/scale_x * double(image_subpixel_scale)); -+ -+ m_ry = uround( scale_y * double(image_subpixel_scale)); -+ m_ry_inv = uround(1.0/scale_y * double(image_subpixel_scale)); - } - - protected: -@@ -219,6 +215,24 @@ namespace agg - m_blur_y = uround(v * double(image_subpixel_scale)); } - - protected: -+ AGG_INLINE void adjust_scale(int* rx, int* ry) -+ { -+ if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; -+ if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; -+ if(*rx > image_subpixel_scale * m_scale_limit) -+ { -+ *rx = image_subpixel_scale * m_scale_limit; -+ } -+ if(*ry > image_subpixel_scale * m_scale_limit) -+ { -+ *ry = image_subpixel_scale * m_scale_limit; -+ } -+ *rx = (*rx * m_blur_x) >> image_subpixel_shift; -+ *ry = (*ry * m_blur_y) >> image_subpixel_shift; -+ if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; -+ if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; -+ } -+ - int m_scale_limit; - int m_blur_x; - int m_blur_y; -diff --git a/src/third_party/agg/include/agg_span_image_filter_gray.h b/src/third_party/agg/include/agg_span_image_filter_gray.h -index bdc30e3..9f3ede7 100644 ---- a/src/third_party/agg/include/agg_span_image_filter_gray.h -+++ b/src/third_party/agg/include/agg_span_image_filter_gray.h -@@ -123,7 +123,6 @@ namespace agg - int x_lr = x_hr >> image_subpixel_shift; - int y_lr = y_hr >> image_subpixel_shift; - -- unsigned weight; - fg = image_subpixel_scale * image_subpixel_scale / 2; - - x_hr &= image_subpixel_mask; -@@ -139,7 +138,7 @@ namespace agg - fg += *fg_ptr * (image_subpixel_scale - x_hr) * y_hr; - - fg_ptr = (const value_type*)base_type::source().next_x(); -- fg += fg_ptr * x_hr * y_hr; -+ fg += *fg_ptr * x_hr * y_hr; - - span->v = value_type(fg >> (image_subpixel_shift * 2)); - span->a = base_mask; -@@ -677,35 +676,10 @@ namespace agg - int ry_inv = image_subpixel_scale; - base_type::interpolator().coordinates(&x, &y); - base_type::interpolator().local_scale(&rx, &ry); -+ base_type::adjust_scale(&rx, &ry); - -- rx = (rx * base_type::m_blur_x) >> image_subpixel_shift; -- ry = (ry * base_type::m_blur_y) >> image_subpixel_shift; -- -- if(rx < image_subpixel_scale) -- { -- rx = image_subpixel_scale; -- } -- else -- { -- if(rx > image_subpixel_scale * base_type::m_scale_limit) -- { -- rx = image_subpixel_scale * base_type::m_scale_limit; -- } -- rx_inv = image_subpixel_scale * image_subpixel_scale / rx; -- } -- -- if(ry < image_subpixel_scale) -- { -- ry = image_subpixel_scale; -- } -- else -- { -- if(ry > image_subpixel_scale * base_type::m_scale_limit) -- { -- ry = image_subpixel_scale * base_type::m_scale_limit; -- } -- ry_inv = image_subpixel_scale * image_subpixel_scale / ry; -- } -+ rx_inv = image_subpixel_scale * image_subpixel_scale / rx; -+ ry_inv = image_subpixel_scale * image_subpixel_scale / ry; - - int radius_x = (diameter * rx) >> 1; - int radius_y = (diameter * ry) >> 1; -diff --git a/src/third_party/agg/include/agg_span_image_filter_rgb.h b/src/third_party/agg/include/agg_span_image_filter_rgb.h -index bd61436..a72ffd2 100644 ---- a/src/third_party/agg/include/agg_span_image_filter_rgb.h -+++ b/src/third_party/agg/include/agg_span_image_filter_rgb.h -@@ -808,35 +808,10 @@ namespace agg - int ry_inv = image_subpixel_scale; - base_type::interpolator().coordinates(&x, &y); - base_type::interpolator().local_scale(&rx, &ry); -+ base_type::adjust_scale(&rx, &ry); - -- rx = (rx * base_type::m_blur_x) >> image_subpixel_shift; -- ry = (ry * base_type::m_blur_y) >> image_subpixel_shift; -- -- if(rx < image_subpixel_scale) -- { -- rx = image_subpixel_scale; -- } -- else -- { -- if(rx > image_subpixel_scale * base_type::m_scale_limit) -- { -- rx = image_subpixel_scale * base_type::m_scale_limit; -- } -- rx_inv = image_subpixel_scale * image_subpixel_scale / rx; -- } -- -- if(ry < image_subpixel_scale) -- { -- ry = image_subpixel_scale; -- } -- else -- { -- if(ry > image_subpixel_scale * base_type::m_scale_limit) -- { -- ry = image_subpixel_scale * base_type::m_scale_limit; -- } -- ry_inv = image_subpixel_scale * image_subpixel_scale / ry; -- } -+ rx_inv = image_subpixel_scale * image_subpixel_scale / rx; -+ ry_inv = image_subpixel_scale * image_subpixel_scale / ry; - - int radius_x = (diameter * rx) >> 1; - int radius_y = (diameter * ry) >> 1; -diff --git a/src/third_party/agg/include/agg_span_image_filter_rgba.h b/src/third_party/agg/include/agg_span_image_filter_rgba.h -index 6d86fcb..d47085c 100644 ---- a/src/third_party/agg/include/agg_span_image_filter_rgba.h -+++ b/src/third_party/agg/include/agg_span_image_filter_rgba.h -@@ -226,7 +226,7 @@ namespace agg - value_type back_b = m_back_color.b; - value_type back_a = m_back_color.a; - -- const value_type *fg_ptr; -+ const value_type *fg_ptr = NULL; - int maxx = base_type::source().width() - 1; - int maxy = base_type::source().height() - 1; - -@@ -832,35 +832,10 @@ namespace agg - int ry_inv = image_subpixel_scale; - base_type::interpolator().coordinates(&x, &y); - base_type::interpolator().local_scale(&rx, &ry); -+ base_type::adjust_scale(&rx, &ry); - -- rx = (rx * base_type::m_blur_x) >> image_subpixel_shift; -- ry = (ry * base_type::m_blur_y) >> image_subpixel_shift; -- -- if(rx < image_subpixel_scale) -- { -- rx = image_subpixel_scale; -- } -- else -- { -- if(rx > image_subpixel_scale * base_type::m_scale_limit) -- { -- rx = image_subpixel_scale * base_type::m_scale_limit; -- } -- rx_inv = image_subpixel_scale * image_subpixel_scale / rx; -- } -- -- if(ry < image_subpixel_scale) -- { -- ry = image_subpixel_scale; -- } -- else -- { -- if(ry > image_subpixel_scale * base_type::m_scale_limit) -- { -- ry = image_subpixel_scale * base_type::m_scale_limit; -- } -- ry_inv = image_subpixel_scale * image_subpixel_scale / ry; -- } -+ rx_inv = image_subpixel_scale * image_subpixel_scale / rx; -+ ry_inv = image_subpixel_scale * image_subpixel_scale / ry; - - int radius_x = (diameter * rx) >> 1; - int radius_y = (diameter * ry) >> 1; -diff --git a/src/third_party/agg/include/agg_span_pattern_gray.h b/src/third_party/agg/include/agg_span_pattern_gray.h -index 83ae9c4..ae1a49f 100644 ---- a/src/third_party/agg/include/agg_span_pattern_gray.h -+++ b/src/third_party/agg/include/agg_span_pattern_gray.h -@@ -50,9 +50,9 @@ namespace agg - {} - - //-------------------------------------------------------------------- -+ void attach(source_type& v) { m_src = &v; } - source_type& source() { return *m_src; } - const source_type& source() const { return *m_src; } -- void set_source(source_type& v) { m_src = &v; } - - //-------------------------------------------------------------------- - void offset_x(unsigned v) { m_offset_x = v; } -diff --git a/src/third_party/agg/include/agg_span_pattern_rgb.h b/src/third_party/agg/include/agg_span_pattern_rgb.h -index d401cb6..4850508 100644 ---- a/src/third_party/agg/include/agg_span_pattern_rgb.h -+++ b/src/third_party/agg/include/agg_span_pattern_rgb.h -@@ -51,9 +51,9 @@ namespace agg - {} - - //-------------------------------------------------------------------- -+ void attach(source_type& v) { m_src = &v; } - source_type& source() { return *m_src; } - const source_type& source() const { return *m_src; } -- void set_source(source_type& v) { m_src = &v; } - - //-------------------------------------------------------------------- - void offset_x(unsigned v) { m_offset_x = v; } -diff --git a/src/third_party/agg/include/agg_span_pattern_rgba.h b/src/third_party/agg/include/agg_span_pattern_rgba.h -index 2725f83..d47d2a6 100644 ---- a/src/third_party/agg/include/agg_span_pattern_rgba.h -+++ b/src/third_party/agg/include/agg_span_pattern_rgba.h -@@ -50,9 +50,9 @@ namespace agg - {} - - //-------------------------------------------------------------------- -+ void attach(source_type& v) { m_src = &v; } - source_type& source() { return *m_src; } - const source_type& source() const { return *m_src; } -- void set_source(source_type& v) { m_src = &v; } - - //-------------------------------------------------------------------- - void offset_x(unsigned v) { m_offset_x = v; } -@@ -75,7 +75,7 @@ namespace agg - span->g = p[order_type::G]; - span->b = p[order_type::B]; - span->a = p[order_type::A]; -- p = m_src->next_x(); -+ p = (const value_type*)m_src->next_x(); - ++span; - } - while(--len); -diff --git a/src/third_party/agg/include/agg_trans_affine.h b/src/third_party/agg/include/agg_trans_affine.h -index edf7ea7..ea5d9cf 100644 ---- a/src/third_party/agg/include/agg_trans_affine.h -+++ b/src/third_party/agg/include/agg_trans_affine.h -@@ -137,12 +137,6 @@ namespace agg - double x1, double y1, - double x2, double y2); - -- const trans_affine& rect_to_rect(double x1, double y1, -- double x2, double y2, -- double x3, double y3, -- double x4, double y4); -- -- - - //------------------------------------------ Operations - // Reset - actually load an identity matrix -@@ -201,14 +195,14 @@ namespace agg - - // Multiply current matrix to another one and return - // the result in a separete matrix. -- trans_affine operator * (const trans_affine& m) -+ trans_affine operator * (const trans_affine& m) const - { - return trans_affine(*this).multiply(m); - } - - // Multiply current matrix to inverse of another one - // and return the result in a separete matrix. -- trans_affine operator / (const trans_affine& m) -+ trans_affine operator / (const trans_affine& m) const - { - return trans_affine(*this).multiply_inv(m); - } -diff --git a/src/third_party/agg/include/agg_vcgen_contour.h b/src/third_party/agg/include/agg_vcgen_contour.h -index c56f026..8c25da1 100644 ---- a/src/third_party/agg/include/agg_vcgen_contour.h -+++ b/src/third_party/agg/include/agg_vcgen_contour.h -@@ -43,22 +43,27 @@ namespace agg - - vcgen_contour(); - -- void line_join(line_join_e lj) { m_line_join = lj; } -- void inner_join(inner_join_e ij) { m_inner_join = ij; } -- void width(double w) { m_width = w * 0.5; } -- void miter_limit(double ml) { m_miter_limit = ml; } -- void miter_limit_theta(double t); -- void inner_miter_limit(double ml) { m_inner_miter_limit = ml; } -- void approximation_scale(double as) { m_approx_scale = as; } -- void auto_detect_orientation(bool v) { m_auto_detect = v; } -+ void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); } -+ void line_join(line_join_e lj) { m_stroker.line_join(lj); } -+ void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); } -+ -+ line_cap_e line_cap() const { return m_stroker.line_cap(); } -+ line_join_e line_join() const { return m_stroker.line_join(); } -+ inner_join_e inner_join() const { return m_stroker.inner_join(); } -+ -+ void width(double w) { m_stroker.width(m_width = w); } -+ void miter_limit(double ml) { m_stroker.miter_limit(ml); } -+ void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); } -+ void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); } -+ void approximation_scale(double as) { m_stroker.approximation_scale(as); } - -- line_join_e line_join() const { return m_line_join; } -- inner_join_e inner_join() const { return m_inner_join; } -- double width() const { return m_width * 2.0; } -- double miter_limit() const { return m_miter_limit; } -- double inner_miter_limit() const { return m_inner_miter_limit; } -- double approximation_scale() const { return m_approx_scale; } -- bool auto_detect_orientation() const { return m_auto_detect; } -+ double width() const { return m_width; } -+ double miter_limit() const { return m_stroker.miter_limit(); } -+ double inner_miter_limit() const { return m_stroker.inner_miter_limit(); } -+ double approximation_scale() const { return m_stroker.approximation_scale(); } -+ -+ void auto_detect_orientation(bool v) { m_auto_detect = v; } -+ bool auto_detect_orientation() const { return m_auto_detect; } - - // Generator interface - void remove_all(); -@@ -72,22 +77,16 @@ namespace agg - vcgen_contour(const vcgen_contour&); - const vcgen_contour& operator = (const vcgen_contour&); - -- vertex_storage m_src_vertices; -- coord_storage m_out_vertices; -- double m_width; -- line_join_e m_line_join; -- inner_join_e m_inner_join; -- double m_approx_scale; -- double m_abs_width; -- double m_signed_width; -- double m_miter_limit; -- double m_inner_miter_limit; -- status_e m_status; -- unsigned m_src_vertex; -- unsigned m_out_vertex; -- unsigned m_closed; -- unsigned m_orientation; -- bool m_auto_detect; -+ math_stroke m_stroker; -+ double m_width; -+ vertex_storage m_src_vertices; -+ coord_storage m_out_vertices; -+ status_e m_status; -+ unsigned m_src_vertex; -+ unsigned m_out_vertex; -+ unsigned m_closed; -+ unsigned m_orientation; -+ bool m_auto_detect; - }; - - } -diff --git a/src/third_party/agg/include/agg_vcgen_stroke.h b/src/third_party/agg/include/agg_vcgen_stroke.h -index e0d9dc5..778223f 100644 ---- a/src/third_party/agg/include/agg_vcgen_stroke.h -+++ b/src/third_party/agg/include/agg_vcgen_stroke.h -@@ -51,24 +51,24 @@ namespace agg - - 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; } -+ void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); } -+ void line_join(line_join_e lj) { m_stroker.line_join(lj); } -+ void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); } - -- line_cap_e line_cap() const { return m_line_cap; } -- line_join_e line_join() const { return m_line_join; } -- inner_join_e inner_join() const { return m_inner_join; } -+ line_cap_e line_cap() const { return m_stroker.line_cap(); } -+ line_join_e line_join() const { return m_stroker.line_join(); } -+ inner_join_e inner_join() const { return m_stroker.inner_join(); } - -- void width(double w) { m_width = w * 0.5; } -- void miter_limit(double ml) { m_miter_limit = ml; } -- void miter_limit_theta(double t); -- void inner_miter_limit(double ml) { m_inner_miter_limit = ml; } -- void approximation_scale(double as) { m_approx_scale = as; } -+ void width(double w) { m_stroker.width(w); } -+ void miter_limit(double ml) { m_stroker.miter_limit(ml); } -+ void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); } -+ void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); } -+ void approximation_scale(double as) { m_stroker.approximation_scale(as); } - -- double width() const { return m_width * 2.0; } -- double miter_limit() const { return m_miter_limit; } -- double inner_miter_limit() const { return m_inner_miter_limit; } -- double approximation_scale() const { return m_approx_scale; } -+ double width() const { return m_stroker.width(); } -+ double miter_limit() const { return m_stroker.miter_limit(); } -+ double inner_miter_limit() const { return m_stroker.inner_miter_limit(); } -+ double approximation_scale() const { return m_stroker.approximation_scale(); } - - void shorten(double s) { m_shorten = s; } - double shorten() const { return m_shorten; } -@@ -85,21 +85,15 @@ namespace agg - vcgen_stroke(const vcgen_stroke&); - const vcgen_stroke& operator = (const vcgen_stroke&); - -- vertex_storage m_src_vertices; -- coord_storage m_out_vertices; -- double m_width; -- double m_miter_limit; -- double m_inner_miter_limit; -- double m_approx_scale; -- double m_shorten; -- line_cap_e m_line_cap; -- line_join_e m_line_join; -- 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; -+ math_stroke m_stroker; -+ vertex_storage m_src_vertices; -+ coord_storage m_out_vertices; -+ double m_shorten; -+ unsigned m_closed; -+ status_e m_status; -+ status_e m_prev_status; -+ unsigned m_src_vertex; -+ unsigned m_out_vertex; - }; - - -diff --git a/src/third_party/agg/include/agg_vertex_sequence.h b/src/third_party/agg/include/agg_vertex_sequence.h -index f9bc915..2ad0701 100644 ---- a/src/third_party/agg/include/agg_vertex_sequence.h -+++ b/src/third_party/agg/include/agg_vertex_sequence.h -@@ -30,7 +30,7 @@ namespace agg - // Modified agg::pod_bvector. The data is interpreted as a sequence - // of vertices. It means that the type T must expose: - // -- // bool operator() (const T& val) -+ // bool T::operator() (const T& val) - // - // that is called every time new vertex is being added. The main purpose - // of this operator is the possibility to calculate some values during -diff --git a/src/third_party/agg/include/agg_vpgen_clip_polyline.h b/src/third_party/agg/include/agg_vpgen_clip_polyline.h -index 6f09856..b070a77 100644 ---- a/src/third_party/agg/include/agg_vpgen_clip_polyline.h -+++ b/src/third_party/agg/include/agg_vpgen_clip_polyline.h -@@ -32,12 +32,9 @@ namespace agg - m_clip_box(0, 0, 1, 1), - m_x1(0), - m_y1(0), -- m_f1(0), -- m_x2(0), -- m_y2(0), -- m_f2(0), - m_num_vertices(0), -- m_vertex(0) -+ m_vertex(0), -+ m_move_to(false) - { - } - -@@ -50,7 +47,6 @@ namespace agg - m_clip_box.normalize(); - } - -- - double x1() const { return m_clip_box.x1; } - double y1() const { return m_clip_box.y1; } - double x2() const { return m_clip_box.x2; } -@@ -64,55 +60,16 @@ namespace agg - void line_to(double x, double y); - unsigned vertex(double* x, double* y); - -- private: -- enum clipping_flags_def -- { -- clip_x1 = 1, -- clip_x2 = 2, -- clip_y1 = 4, -- clip_y2 = 8 -- }; -- -- // Determine the clipping code of the vertex according to the -- // Cyrus-Beck line clipping algorithm -- //-------------------------------------------------------------------- -- unsigned clipping_flags_x(double x) -- { -- unsigned f = 0; -- if(x < m_clip_box.x1) f |= clip_x1; -- if(x > m_clip_box.x2) f |= clip_x2; -- return f; -- } -- -- unsigned clipping_flags_y(double y) -- { -- unsigned f = 0; -- if(y < m_clip_box.y1) f |= clip_y1; -- if(y > m_clip_box.y2) f |= clip_y2; -- return f; -- } -- -- unsigned clipping_flags(double x, double y) -- { -- return clipping_flags_x(x) | clipping_flags_y(y); -- } -- -- bool move_point(double& x, double& y, unsigned& flags); -- void clip_line_segment(); -- - private: - rect_d m_clip_box; - double m_x1; - double m_y1; -- unsigned m_f1; -- double m_x2; -- double m_y2; -- unsigned m_f2; - double m_x[2]; - double m_y[2]; - unsigned m_cmd[2]; - unsigned m_num_vertices; - unsigned m_vertex; -+ bool m_move_to; - }; - - } -diff --git a/src/third_party/agg/include/dbg_new/agg_dbg_new.h b/src/third_party/agg/include/dbg_new/agg_dbg_new.h -new file mode 100644 -index 0000000..687358d ---- /dev/null -+++ b/src/third_party/agg/include/dbg_new/agg_dbg_new.h -@@ -0,0 +1,79 @@ -+//---------------------------------------------------------------------------- -+// Anti-Grain Geometry - Version 2.2 -+// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) -+// -+// Permission to copy, use, modify, sell and distribute this software -+// is granted provided this copyright notice appears in all copies. -+// This software is provided "as is" without express or implied -+// warranty, and with no claim as to its suitability for any purpose. -+// -+//---------------------------------------------------------------------------- -+// Contact: mcseem@antigrain.com -+// mcseemagg@yahoo.com -+// http://www.antigrain.com -+//---------------------------------------------------------------------------- -+// -+// Debuging stuff for catching memory leaks and corruptions -+// -+//---------------------------------------------------------------------------- -+#ifndef AGG_DBG_NEW_INCLUDED -+#define AGG_DBG_NEW_INCLUDED -+ -+#ifdef _WIN32 -+#include -+#include -+#endif -+ -+//#define AGG_DBG_NEW_CHECK_ADDR -+ -+void* operator new (unsigned size, const char* file, int line); -+void* operator new [] (unsigned size, const char* file, int line); -+#define AGG_DBG_NEW_OPERATOR new(__FILE__, __LINE__) -+ -+void operator delete(void *ptr) throw(); -+void operator delete [] (void *ptr) throw(); -+ -+namespace agg -+{ -+ #ifdef _WIN32 -+ inline void printf(char* fmt, ...) -+ { -+ FILE* fd = fopen("stdout.txt", "at"); -+ static char msg[1024]; -+ va_list arg; -+ va_start(arg, fmt); -+ vsprintf(msg, fmt, arg); -+ va_end(arg); -+ fputs(msg, fd); -+ fclose(fd); -+ } -+ #endif -+ -+ enum { max_dbg_new_level = 32 }; -+ -+#ifdef AGG_DBG_NEW_CHECK_ADDR -+ enum { max_allocations = 4096 }; -+#endif -+ -+ // All you need to watch for memory in heap is to declare an object -+ // of this class in your main() or whatever function you need. -+ // It will report you about all bad things happend to new/delete. -+ // Try not to exceed the maximal nested level of declared watchdoggies -+ // (max_dbg_new_level) -+ class watchdoggy -+ { -+ public: -+ watchdoggy(const char* file=0, int line=0, bool report_all=false); -+ ~watchdoggy(); -+ }; -+} -+ -+#define AGG_WATCHDOGGY(name, report_all) \ -+ agg::watchdoggy name(__FILE__, __LINE__, report_all); -+#endif -+ -+#ifdef new -+#undef new -+#endif -+#define new AGG_DBG_NEW_OPERATOR -+ -diff --git a/src/third_party/agg/include/util/agg_color_conv.h b/src/third_party/agg/include/util/agg_color_conv.h -index 6e27690..fd7aeea 100644 ---- a/src/third_party/agg/include/util/agg_color_conv.h -+++ b/src/third_party/agg/include/util/agg_color_conv.h -@@ -1,6 +1,6 @@ - //---------------------------------------------------------------------------- --// Anti-Grain Geometry - Version 2.4 --// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -+// Anti-Grain Geometry - Version 2.2 -+// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) - // - // Permission to copy, use, modify, sell and distribute this software - // is granted provided this copyright notice appears in all copies. -@@ -31,8 +31,10 @@ namespace agg - { - - //--------------------------------------------------------------color_conv -- template -- void color_conv(RenBuf* dst, const RenBuf* src, CopyRow copy_row_functor) -+ template -+ void color_conv(rendering_buffer* dst, -+ const rendering_buffer* src, -+ CopyRow copy_row_functor) - { - unsigned width = src->width(); - unsigned height = src->height(); -@@ -45,9 +47,7 @@ namespace agg - unsigned y; - for(y = 0; y < height; y++) - { -- copy_row_functor(dst->row_ptr(0, y, width), -- src->row_ptr(y), -- width); -+ copy_row_functor(dst->row(y), src->row(y), width); - } - } - } -@@ -55,8 +55,8 @@ namespace agg - - //---------------------------------------------------------color_conv_row - template -- void color_conv_row(int8u* dst, -- const int8u* src, -+ void color_conv_row(unsigned char* dst, -+ const unsigned char* src, - unsigned width, - CopyRow copy_row_functor) - { -@@ -68,8 +68,8 @@ namespace agg - template class color_conv_same - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - memmove(dst, src, width*BPP); -diff --git a/src/third_party/agg/include/util/agg_color_conv_rgb16.h b/src/third_party/agg/include/util/agg_color_conv_rgb16.h -deleted file mode 100644 -index aaa4132..0000000 ---- a/src/third_party/agg/include/util/agg_color_conv_rgb16.h -+++ /dev/null -@@ -1,285 +0,0 @@ --//---------------------------------------------------------------------------- --// Anti-Grain Geometry - Version 2.4 --// Copyright (C) 2002-2005 Maxim Shemanarev (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 --//---------------------------------------------------------------------------- --// --// This part of the library 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. --// --//---------------------------------------------------------------------------- --// --// A set of functors used with color_conv(). See file agg_color_conv.h --// These functors can convert images with up to 8 bits per component. --// Use convertors in the following way: --// --// agg::color_conv(dst, src, agg::color_conv_XXXX_to_YYYY()); --//---------------------------------------------------------------------------- -- --#ifndef AGG_COLOR_CONV_RGB16_INCLUDED --#define AGG_COLOR_CONV_RGB16_INCLUDED -- --#include "agg_basics.h" --#include "agg_color_conv.h" -- --namespace agg --{ -- -- //-------------------------------------------------color_conv_gray16_to_gray8 -- class color_conv_gray16_to_gray8 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- int16u* s = (int16u*)src; -- do -- { -- *dst++ = *s++ >> 8; -- } -- while(--width); -- } -- }; -- -- -- //-----------------------------------------------------color_conv_rgb24_rgb48 -- template class color_conv_rgb24_rgb48 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- int16u* d = (int16u*)dst; -- do -- { -- *d++ = (src[I1] << 8) | src[I1]; -- *d++ = (src[1] << 8) | src[1] ; -- *d++ = (src[I3] << 8) | src[I3]; -- src += 3; -- } -- while(--width); -- } -- }; -- -- typedef color_conv_rgb24_rgb48<0,2> color_conv_rgb24_to_rgb48; -- typedef color_conv_rgb24_rgb48<0,2> color_conv_bgr24_to_bgr48; -- typedef color_conv_rgb24_rgb48<2,0> color_conv_rgb24_to_bgr48; -- typedef color_conv_rgb24_rgb48<2,0> color_conv_bgr24_to_rgb48; -- -- -- //-----------------------------------------------------color_conv_rgb24_rgb48 -- template class color_conv_rgb48_rgb24 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- const int16u* s = (const int16u*)src; -- do -- { -- *dst++ = s[I1] >> 8; -- *dst++ = s[1] >> 8; -- *dst++ = s[I3] >> 8; -- s += 3; -- } -- while(--width); -- } -- }; -- -- typedef color_conv_rgb48_rgb24<0,2> color_conv_rgb48_to_rgb24; -- typedef color_conv_rgb48_rgb24<0,2> color_conv_bgr48_to_bgr24; -- typedef color_conv_rgb48_rgb24<2,0> color_conv_rgb48_to_bgr24; -- typedef color_conv_rgb48_rgb24<2,0> color_conv_bgr48_to_rgb24; -- -- -- //----------------------------------------------color_conv_rgbAAA_rgb24 -- template class color_conv_rgbAAA_rgb24 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- do -- { -- int32u rgb = *(int32u*)src; -- dst[R] = int8u(rgb >> 22); -- dst[1] = int8u(rgb >> 12); -- dst[B] = int8u(rgb >> 2); -- src += 4; -- dst += 3; -- } -- while(--width); -- } -- }; -- -- typedef color_conv_rgbAAA_rgb24<0,2> color_conv_rgbAAA_to_rgb24; -- typedef color_conv_rgbAAA_rgb24<2,0> color_conv_rgbAAA_to_bgr24; -- typedef color_conv_rgbAAA_rgb24<2,0> color_conv_bgrAAA_to_rgb24; -- typedef color_conv_rgbAAA_rgb24<0,2> color_conv_bgrAAA_to_bgr24; -- -- -- //----------------------------------------------color_conv_rgbBBA_rgb24 -- template class color_conv_rgbBBA_rgb24 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- do -- { -- int32u rgb = *(int32u*)src; -- dst[R] = int8u(rgb >> 24); -- dst[1] = int8u(rgb >> 13); -- dst[B] = int8u(rgb >> 2); -- src += 4; -- dst += 3; -- } -- while(--width); -- } -- }; -- -- typedef color_conv_rgbBBA_rgb24<0,2> color_conv_rgbBBA_to_rgb24; -- typedef color_conv_rgbBBA_rgb24<2,0> color_conv_rgbBBA_to_bgr24; -- -- -- //----------------------------------------------color_conv_bgrABB_rgb24 -- template class color_conv_bgrABB_rgb24 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- do -- { -- int32u bgr = *(int32u*)src; -- dst[R] = int8u(bgr >> 3); -- dst[1] = int8u(bgr >> 14); -- dst[B] = int8u(bgr >> 24); -- src += 4; -- dst += 3; -- } -- while(--width); -- } -- }; -- -- typedef color_conv_bgrABB_rgb24<2,0> color_conv_bgrABB_to_rgb24; -- typedef color_conv_bgrABB_rgb24<0,2> color_conv_bgrABB_to_bgr24; -- -- -- //-------------------------------------------------color_conv_rgba64_rgba32 -- template class color_conv_rgba64_rgba32 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- do -- { -- *dst++ = int8u(((int16u*)src)[I1] >> 8); -- *dst++ = int8u(((int16u*)src)[I2] >> 8); -- *dst++ = int8u(((int16u*)src)[I3] >> 8); -- *dst++ = int8u(((int16u*)src)[I4] >> 8); -- src += 8; -- } -- while(--width); -- } -- }; -- -- //------------------------------------------------------------------------ -- typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_rgba64_to_rgba32; //----color_conv_rgba64_to_rgba32 -- typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_argb64_to_argb32; //----color_conv_argb64_to_argb32 -- typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_bgra64_to_bgra32; //----color_conv_bgra64_to_bgra32 -- typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_abgr64_to_abgr32; //----color_conv_abgr64_to_abgr32 -- typedef color_conv_rgba64_rgba32<0,3,2,1> color_conv_argb64_to_abgr32; //----color_conv_argb64_to_abgr32 -- typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_argb64_to_bgra32; //----color_conv_argb64_to_bgra32 -- typedef color_conv_rgba64_rgba32<1,2,3,0> color_conv_argb64_to_rgba32; //----color_conv_argb64_to_rgba32 -- typedef color_conv_rgba64_rgba32<3,0,1,2> color_conv_bgra64_to_abgr32; //----color_conv_bgra64_to_abgr32 -- typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_bgra64_to_argb32; //----color_conv_bgra64_to_argb32 -- typedef color_conv_rgba64_rgba32<2,1,0,3> color_conv_bgra64_to_rgba32; //----color_conv_bgra64_to_rgba32 -- typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_rgba64_to_abgr32; //----color_conv_rgba64_to_abgr32 -- typedef color_conv_rgba64_rgba32<3,0,1,2> color_conv_rgba64_to_argb32; //----color_conv_rgba64_to_argb32 -- typedef color_conv_rgba64_rgba32<2,1,0,3> color_conv_rgba64_to_bgra32; //----color_conv_rgba64_to_bgra32 -- typedef color_conv_rgba64_rgba32<0,3,2,1> color_conv_abgr64_to_argb32; //----color_conv_abgr64_to_argb32 -- typedef color_conv_rgba64_rgba32<1,2,3,0> color_conv_abgr64_to_bgra32; //----color_conv_abgr64_to_bgra32 -- typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_abgr64_to_rgba32; //----color_conv_abgr64_to_rgba32 -- -- -- -- //--------------------------------------------color_conv_rgb24_rgba64 -- template class color_conv_rgb24_rgba64 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- int16u* d = (int16u*)dst; -- do -- { -- d[I1] = (src[0] << 8) | src[0]; -- d[I2] = (src[1] << 8) | src[1]; -- d[I3] = (src[2] << 8) | src[2]; -- d[A] = 65535; -- d += 4; -- src += 3; -- } -- while(--width); -- } -- }; -- -- -- //------------------------------------------------------------------------ -- typedef color_conv_rgb24_rgba64<1,2,3,0> color_conv_rgb24_to_argb64; //----color_conv_rgb24_to_argb64 -- typedef color_conv_rgb24_rgba64<3,2,1,0> color_conv_rgb24_to_abgr64; //----color_conv_rgb24_to_abgr64 -- typedef color_conv_rgb24_rgba64<2,1,0,3> color_conv_rgb24_to_bgra64; //----color_conv_rgb24_to_bgra64 -- typedef color_conv_rgb24_rgba64<0,1,2,3> color_conv_rgb24_to_rgba64; //----color_conv_rgb24_to_rgba64 -- typedef color_conv_rgb24_rgba64<3,2,1,0> color_conv_bgr24_to_argb64; //----color_conv_bgr24_to_argb64 -- typedef color_conv_rgb24_rgba64<1,2,3,0> color_conv_bgr24_to_abgr64; //----color_conv_bgr24_to_abgr64 -- typedef color_conv_rgb24_rgba64<0,1,2,3> color_conv_bgr24_to_bgra64; //----color_conv_bgr24_to_bgra64 -- typedef color_conv_rgb24_rgba64<2,1,0,3> color_conv_bgr24_to_rgba64; //----color_conv_bgr24_to_rgba64 -- -- -- template class color_conv_rgb24_gray16 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- int16u* d = (int16u*)dst; -- do -- { -- *d++ = src[R]*77 + src[1]*150 + src[B]*29; -- src += 3; -- } -- while(--width); -- } -- }; -- -- typedef color_conv_rgb24_gray16<0,2> color_conv_rgb24_to_gray16; -- typedef color_conv_rgb24_gray16<2,0> color_conv_bgr24_to_gray16; -- -- --} -- -- --#endif -diff --git a/src/third_party/agg/include/util/agg_color_conv_rgb8.h b/src/third_party/agg/include/util/agg_color_conv_rgb8.h -index 4268b5a..fdf9cf4 100644 ---- a/src/third_party/agg/include/util/agg_color_conv_rgb8.h -+++ b/src/third_party/agg/include/util/agg_color_conv_rgb8.h -@@ -1,6 +1,6 @@ - //---------------------------------------------------------------------------- --// Anti-Grain Geometry - Version 2.4 --// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -+// Anti-Grain Geometry - Version 2.2 -+// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) - // - // Permission to copy, use, modify, sell and distribute this software - // is granted provided this copyright notice appears in all copies. -@@ -42,8 +42,8 @@ namespace agg - class color_conv_rgb24 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -69,8 +69,8 @@ namespace agg - template class color_conv_rgba32 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -111,8 +111,8 @@ namespace agg - template class color_conv_rgb24_rgba32 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -144,8 +144,8 @@ namespace agg - template class color_conv_rgba32_rgb24 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -176,16 +176,16 @@ namespace agg - template class color_conv_rgb555_rgb24 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do - { - unsigned rgb = *(int16u*)src; -- dst[R] = (int8u)((rgb >> 7) & 0xF8); -- dst[1] = (int8u)((rgb >> 2) & 0xF8); -- dst[B] = (int8u)((rgb << 3) & 0xF8); -+ dst[R] = (unsigned char)((rgb >> 7) & 0xF8); -+ dst[1] = (unsigned char)((rgb >> 2) & 0xF8); -+ dst[B] = (unsigned char)((rgb << 3) & 0xF8); - src += 2; - dst += 3; - } -@@ -203,8 +203,8 @@ namespace agg - template class color_conv_rgb24_rgb555 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -229,8 +229,8 @@ namespace agg - template class color_conv_rgb565_rgb24 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -256,8 +256,8 @@ namespace agg - template class color_conv_rgb24_rgb565 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -283,8 +283,8 @@ namespace agg - template class color_conv_rgb555_rgba32 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -313,8 +313,8 @@ namespace agg - template class color_conv_rgba32_rgb555 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -343,8 +343,8 @@ namespace agg - template class color_conv_rgb565_rgba32 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -373,8 +373,8 @@ namespace agg - template class color_conv_rgba32_rgb565 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -401,8 +401,8 @@ namespace agg - class color_conv_rgb555_to_rgb565 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -421,8 +421,8 @@ namespace agg - class color_conv_rgb565_to_rgb555 - { - public: -- void operator () (int8u* dst, -- const int8u* src, -+ void operator () (unsigned char* dst, -+ const unsigned char* src, - unsigned width) const - { - do -@@ -440,27 +440,7 @@ namespace agg - //------------------------------------------------------------------------ - typedef color_conv_same<2> color_conv_rgb555_to_rgb555; //----color_conv_rgb555_to_rgb555 - typedef color_conv_same<2> color_conv_rgb565_to_rgb565; //----color_conv_rgb565_to_rgb565 -- - -- template class color_conv_rgb24_gray8 -- { -- public: -- void operator () (int8u* dst, -- const int8u* src, -- unsigned width) const -- { -- do -- { -- *dst++ = (src[R]*77 + src[1]*150 + src[B]*29) >> 8; -- src += 3; -- } -- while(--width); -- } -- }; -- -- typedef color_conv_rgb24_gray8<0,2> color_conv_rgb24_to_gray8; //----color_conv_rgb24_to_gray8 -- typedef color_conv_rgb24_gray8<2,0> color_conv_bgr24_to_gray8; //----color_conv_bgr24_to_gray8 -- - - } - -diff --git a/src/third_party/agg/src/agg_bspline.cpp b/src/third_party/agg/src/agg_bspline.cpp -index 2dc4e1b..e1fda9f 100644 ---- a/src/third_party/agg/src/agg_bspline.cpp -+++ b/src/third_party/agg/src/agg_bspline.cpp -@@ -17,26 +17,16 @@ - // - //---------------------------------------------------------------------------- - -- - #include "agg_bspline.h" - - namespace agg - { -- -- //------------------------------------------------------------------------ -- bspline::~bspline() -- { -- delete [] m_am; -- } -- -- - //------------------------------------------------------------------------ - bspline::bspline() : - m_max(0), - m_num(0), - m_x(0), - m_y(0), -- m_am(0), - m_last_idx(-1) - { - } -@@ -47,7 +37,6 @@ namespace agg - m_num(0), - m_x(0), - m_y(0), -- m_am(0), - m_last_idx(-1) - { - init(num); -@@ -59,7 +48,6 @@ namespace agg - m_num(0), - m_x(0), - m_y(0), -- m_am(0), - m_last_idx(-1) - { - init(num, x, y); -@@ -71,11 +59,10 @@ namespace agg - { - if(max > 2 && max > m_max) - { -- delete [] m_am; -- m_am = new double[max * 3]; -+ m_am.resize(max * 3); - m_max = max; -- m_x = m_am + m_max; -- m_y = m_am + m_max * 2; -+ m_x = &m_am[m_max]; -+ m_y = &m_am[m_max * 2]; - } - m_num = 0; - m_last_idx = -1; -@@ -103,7 +90,6 @@ namespace agg - double* temp; - double* r; - double* s; -- double* al; - double h, p, d, f, e; - - for(k = 0; k < m_num; k++) -@@ -113,8 +99,8 @@ namespace agg - - n1 = 3 * m_num; - -- al = new double[n1]; -- temp = al; -+ pod_array al(n1); -+ temp = &al[0]; - - for(k = 0; k < n1; k++) - { -@@ -155,7 +141,6 @@ namespace agg - al[k] = al[k] * al[k + 1] + s[k]; - m_am[k] = al[k]; - } -- delete [] al; - } - m_last_idx = -1; - } -diff --git a/src/third_party/agg/src/agg_curves.cpp b/src/third_party/agg/src/agg_curves.cpp -index 5cdf65e..4701734 100644 ---- a/src/third_party/agg/src/agg_curves.cpp -+++ b/src/third_party/agg/src/agg_curves.cpp -@@ -82,9 +82,6 @@ namespace agg - m_step = m_num_steps; - } - -- -- -- - //------------------------------------------------------------------------ - void curve3_inc::rewind(unsigned) - { -@@ -100,9 +97,6 @@ namespace agg - m_dfy = m_saved_dfy; - } - -- -- -- - //------------------------------------------------------------------------ - unsigned curve3_inc::vertex(double* x, double* y) - { -@@ -131,7 +125,6 @@ namespace agg - return path_cmd_line_to; - } - -- - //------------------------------------------------------------------------ - void curve3_div::init(double x1, double y1, - double x2, double y2, -@@ -140,12 +133,10 @@ namespace agg - m_points.remove_all(); - m_distance_tolerance_square = 0.5 / m_approximation_scale; - m_distance_tolerance_square *= m_distance_tolerance_square; -- m_distance_tolerance_manhattan = 4.0 / m_approximation_scale; - bezier(x1, y1, x2, y2, x3, y3); - m_count = 0; - } - -- - //------------------------------------------------------------------------ - void curve3_div::recursive_bezier(double x1, double y1, - double x2, double y2, -@@ -169,10 +160,11 @@ namespace agg - double dx = x3-x1; - double dy = y3-y1; - double d = fabs(((x2 - x3) * dy - (y2 - y3) * dx)); -+ double da; - - if(d > curve_collinearity_epsilon) - { -- // Regular care -+ // Regular case - //----------------- - if(d * d <= m_distance_tolerance_square * (dx*dx + dy*dy)) - { -@@ -187,7 +179,7 @@ namespace agg - - // Angle & Cusp Condition - //---------------------- -- double da = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1)); -+ da = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1)); - if(da >= pi) da = 2*pi - da; - - if(da < m_angle_tolerance) -@@ -201,12 +193,31 @@ namespace agg - } - else - { -- if(fabs(x1 + x3 - x2 - x2) + -- fabs(y1 + y3 - y2 - y2) <= m_distance_tolerance_manhattan) -+ // Collinear case -+ //------------------ -+ da = dx*dx + dy*dy; -+ if(da == 0) -+ { -+ d = calc_sq_distance(x1, y1, x2, y2); -+ } -+ else -+ { -+ d = ((x2 - x1)*dx + (y2 - y1)*dy) / da; -+ if(d > 0 && d < 1) -+ { -+ // Simple collinear case, 1---2---3 -+ // We can leave just two endpoints -+ return; -+ } -+ if(d <= 0) d = calc_sq_distance(x2, y2, x1, y1); -+ else if(d >= 1) d = calc_sq_distance(x2, y2, x3, y3); -+ else d = calc_sq_distance(x2, y2, x1 + d*dx, y1 + d*dy); -+ } -+ if(d < m_distance_tolerance_square) - { -- m_points.add(point_d(x123, y123)); -+ m_points.add(point_d(x2, y2)); - return; -- } -+ } - } - - // Continue subdivision -@@ -241,8 +252,10 @@ namespace agg - return m_scale; - } - -+#if defined(_MSC_VER) && _MSC_VER <= 1200 - //------------------------------------------------------------------------ - static double MSC60_fix_ICE(double v) { return v; } -+#endif - - //------------------------------------------------------------------------ - void curve4_inc::init(double x1, double y1, -@@ -262,9 +275,9 @@ namespace agg - double dx3 = x4 - x3; - double dy3 = y4 - y3; - -- double len = sqrt(dx1 * dx1 + dy1 * dy1) + -- sqrt(dx2 * dx2 + dy2 * dy2) + -- sqrt(dx3 * dx3 + dy3 * dy3) * 0.25 * m_scale; -+ double len = (sqrt(dx1 * dx1 + dy1 * dy1) + -+ sqrt(dx2 * dx2 + dy2 * dy2) + -+ sqrt(dx3 * dx3 + dy3 * dy3)) * 0.25 * m_scale; - - #if defined(_MSC_VER) && _MSC_VER <= 1200 - m_num_steps = uround(MSC60_fix_ICE(len)); -@@ -307,9 +320,6 @@ namespace agg - m_step = m_num_steps; - } - -- -- -- - //------------------------------------------------------------------------ - void curve4_inc::rewind(unsigned) - { -@@ -327,10 +337,6 @@ namespace agg - m_ddfy = m_saved_ddfy; - } - -- -- -- -- - //------------------------------------------------------------------------ - unsigned curve4_inc::vertex(double* x, double* y) - { -@@ -376,12 +382,10 @@ namespace agg - m_points.remove_all(); - m_distance_tolerance_square = 0.5 / m_approximation_scale; - m_distance_tolerance_square *= m_distance_tolerance_square; -- m_distance_tolerance_manhattan = 4.0 / m_approximation_scale; - bezier(x1, y1, x2, y2, x3, y3, x4, y4); - m_count = 0; - } - -- - //------------------------------------------------------------------------ - void curve4_div::recursive_bezier(double x1, double y1, - double x2, double y2, -@@ -409,6 +413,7 @@ namespace agg - double x1234 = (x123 + x234) / 2; - double y1234 = (y123 + y234) / 2; - -+ - // Try to approximate the full cubic curve by a single straight line - //------------------ - double dx = x4-x1; -@@ -416,7 +421,7 @@ namespace agg - - double d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx)); - double d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx)); -- double da1, da2; -+ double da1, da2, k; - - switch((int(d2 > curve_collinearity_epsilon) << 1) + - int(d3 > curve_collinearity_epsilon)) -@@ -424,18 +429,55 @@ namespace agg - case 0: - // All collinear OR p1==p4 - //---------------------- -- if(fabs(x1 + x3 - x2 - x2) + -- fabs(y1 + y3 - y2 - y2) + -- fabs(x2 + x4 - x3 - x3) + -- fabs(y2 + y4 - y3 - y3) <= m_distance_tolerance_manhattan) -+ k = dx*dx + dy*dy; -+ if(k == 0) - { -- m_points.add(point_d(x1234, y1234)); -- return; -- } -+ d2 = calc_sq_distance(x1, y1, x2, y2); -+ d3 = calc_sq_distance(x4, y4, x3, y3); -+ } -+ else -+ { -+ k = 1 / k; -+ da1 = x2 - x1; -+ da2 = y2 - y1; -+ d2 = k * (da1*dx + da2*dy); -+ da1 = x3 - x1; -+ da2 = y3 - y1; -+ d3 = k * (da1*dx + da2*dy); -+ if(d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1) -+ { -+ // Simple collinear case, 1---2---3---4 -+ // We can leave just two endpoints -+ return; -+ } -+ if(d2 <= 0) d2 = calc_sq_distance(x2, y2, x1, y1); -+ else if(d2 >= 1) d2 = calc_sq_distance(x2, y2, x4, y4); -+ else d2 = calc_sq_distance(x2, y2, x1 + d2*dx, y1 + d2*dy); -+ -+ if(d3 <= 0) d3 = calc_sq_distance(x3, y3, x1, y1); -+ else if(d3 >= 1) d3 = calc_sq_distance(x3, y3, x4, y4); -+ else d3 = calc_sq_distance(x3, y3, x1 + d3*dx, y1 + d3*dy); -+ } -+ if(d2 > d3) -+ { -+ if(d2 < m_distance_tolerance_square) -+ { -+ m_points.add(point_d(x2, y2)); -+ return; -+ } -+ } -+ else -+ { -+ if(d3 < m_distance_tolerance_square) -+ { -+ m_points.add(point_d(x3, y3)); -+ return; -+ } -+ } - break; - - case 1: -- // p1,p2,p4 are collinear, p3 is considerable -+ // p1,p2,p4 are collinear, p3 is significant - //---------------------- - if(d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy)) - { -@@ -469,7 +511,7 @@ namespace agg - break; - - case 2: -- // p1,p3,p4 are collinear, p2 is considerable -+ // p1,p3,p4 are collinear, p2 is significant - //---------------------- - if(d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy)) - { -@@ -503,7 +545,7 @@ namespace agg - break; - - case 3: -- // Regular care -+ // Regular case - //----------------- - if((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy)) - { -@@ -518,9 +560,9 @@ namespace agg - - // Angle & Cusp Condition - //---------------------- -- double a23 = atan2(y3 - y2, x3 - x2); -- da1 = fabs(a23 - atan2(y2 - y1, x2 - x1)); -- da2 = fabs(atan2(y4 - y3, x4 - x3) - a23); -+ k = atan2(y3 - y2, x3 - x2); -+ da1 = fabs(k - atan2(y2 - y1, x2 - x1)); -+ da2 = fabs(atan2(y4 - y3, x4 - x3) - k); - if(da1 >= pi) da1 = 2*pi - da1; - if(da2 >= pi) da2 = 2*pi - da2; - -diff --git a/src/third_party/agg/src/agg_gsv_text.cpp b/src/third_party/agg/src/agg_gsv_text.cpp -index 0ccc64b..901e2c5 100644 ---- a/src/third_party/agg/src/agg_gsv_text.cpp -+++ b/src/third_party/agg/src/agg_gsv_text.cpp -@@ -480,16 +480,6 @@ namespace agg - 0xf6,0xfa,0x04,0x06,0x08,0xfa - }; - -- -- -- //------------------------------------------------------------------------- -- gsv_text::~gsv_text() -- { -- if(m_loaded_font) delete [] m_loaded_font; -- if(m_text_buf) delete [] m_text_buf; -- } -- -- - //------------------------------------------------------------------------- - gsv_text::gsv_text() : - m_x(0.0), -@@ -500,11 +490,10 @@ namespace agg - m_space(0.0), - m_line_space(0.0), - m_text(m_chr), -- m_text_buf(0), -- m_buf_size(0), -+ m_text_buf(), - m_cur_chr(m_chr), - m_font(gsv_default_font), -- m_loaded_font(0), -+ m_loaded_font(), - m_status(initial), - m_big_endian(false), - m_flip(false) -@@ -521,7 +510,7 @@ namespace agg - void gsv_text::font(const void* font) - { - m_font = font; -- if(m_font == 0) m_font = m_loaded_font; -+ if(m_font == 0) m_font = &m_loaded_font[0]; - } - - //------------------------------------------------------------------------- -@@ -555,9 +544,7 @@ namespace agg - //------------------------------------------------------------------------- - void gsv_text::load_font(const char* file) - { -- if(m_loaded_font) delete [] m_loaded_font; -- m_loaded_font = 0; -- -+ m_loaded_font.resize(0); - FILE* fd = fopen(file, "rb"); - if(fd) - { -@@ -568,9 +555,9 @@ namespace agg - fseek(fd, 0l, SEEK_SET); - if(len > 0) - { -- m_loaded_font = new char [len]; -- fread(m_loaded_font, 1, len, fd); -- m_font = m_loaded_font; -+ m_loaded_font.resize(len); -+ fread(&m_loaded_font[0], 1, len, fd); -+ m_font = &m_loaded_font[0]; - } - fclose(fd); - } -@@ -587,13 +574,12 @@ namespace agg - return; - } - unsigned new_size = strlen(text) + 1; -- if(new_size > m_buf_size) -+ if(new_size > m_text_buf.size()) - { -- if(m_text_buf) delete [] m_text_buf; -- m_text_buf = new char [m_buf_size = new_size]; -+ m_text_buf.resize(new_size); - } -- memcpy(m_text_buf, text, new_size); -- m_text = m_text_buf; -+ memcpy(&m_text_buf[0], text, new_size); -+ m_text = &m_text_buf[0]; - } - - -diff --git a/src/third_party/agg/src/agg_image_filters.cpp b/src/third_party/agg/src/agg_image_filters.cpp -index 531a056..549d9ad 100644 ---- a/src/third_party/agg/src/agg_image_filters.cpp -+++ b/src/third_party/agg/src/agg_image_filters.cpp -@@ -23,20 +23,6 @@ - - namespace agg - { -- -- //-------------------------------------------------------------------- -- image_filter_lut::~image_filter_lut() -- { -- delete [] m_weight_array; -- } -- -- -- //-------------------------------------------------------------------- -- image_filter_lut::image_filter_lut() : -- m_weight_array(0), -- m_max_size(0) -- {} -- - //-------------------------------------------------------------------- - void image_filter_lut::realloc_lut(double radius) - { -@@ -44,11 +30,9 @@ namespace agg - m_diameter = uceil(radius) * 2; - m_start = -int(m_diameter / 2 - 1); - unsigned size = m_diameter << image_subpixel_shift; -- if(size > m_max_size) -+ if(size > m_weight_array.size()) - { -- delete [] m_weight_array; -- m_weight_array = new int16 [size]; -- m_max_size = size; -+ m_weight_array.resize(size); - } - } - -diff --git a/src/third_party/agg/src/agg_line_aa_basics.cpp b/src/third_party/agg/src/agg_line_aa_basics.cpp -index ec6e854..018d653 100644 ---- a/src/third_party/agg/src/agg_line_aa_basics.cpp -+++ b/src/third_party/agg/src/agg_line_aa_basics.cpp -@@ -41,9 +41,9 @@ namespace agg - // (7)111 | 101(5) - // [2] | [3] - // <3> -- // 0,1,2,3,4,5,6,7 -- int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 }; -- int8u line_parameters::s_diagonal_quadrant[8] = { 0,1,2,1,0,3,2,3 }; -+ // 0,1,2,3,4,5,6,7 -+ const int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 }; -+ const int8u line_parameters::s_diagonal_quadrant[8] = { 0,1,2,1,0,3,2,3 }; - - - -diff --git a/src/third_party/agg/src/agg_line_profile_aa.cpp b/src/third_party/agg/src/agg_line_profile_aa.cpp -index 6646ded..6066662 100644 ---- a/src/third_party/agg/src/agg_line_profile_aa.cpp -+++ b/src/third_party/agg/src/agg_line_profile_aa.cpp -@@ -44,12 +44,11 @@ namespace agg - { - m_subpixel_width = uround(w * subpixel_scale); - unsigned size = m_subpixel_width + subpixel_scale * 6; -- if(size > m_size) -+ if(size > m_profile.size()) - { -- delete [] m_profile; -- m_profile = new value_type[m_size = size]; -+ m_profile.resize(size); - } -- return m_profile; -+ return &m_profile[0]; - } - - -diff --git a/src/third_party/agg/src/agg_trans_affine.cpp b/src/third_party/agg/src/agg_trans_affine.cpp -index 568f9f9..b8a1851 100644 ---- a/src/third_party/agg/src/agg_trans_affine.cpp -+++ b/src/third_party/agg/src/agg_trans_affine.cpp -@@ -66,26 +66,6 @@ namespace agg - return *this; - } - -- //------------------------------------------------------------------------ -- const trans_affine& trans_affine::rect_to_rect(double x1, double y1, -- double x2, double y2, -- double x3, double y3, -- double x4, double y4) -- { -- double src[6]; -- src[0] = x1; src[1] = y1; -- src[2] = x2; src[3] = y1; -- src[4] = x2; src[5] = y2; -- -- double dst[6]; -- dst[0] = x3; dst[1] = y3; -- dst[2] = x4; dst[3] = y3; -- dst[4] = x4; dst[5] = y4; -- -- parl_to_parl(src, dst); -- return *this; -- } -- - //------------------------------------------------------------------------ - const trans_affine& trans_affine::multiply(const trans_affine& m) - { -diff --git a/src/third_party/agg/src/agg_vcgen_contour.cpp b/src/third_party/agg/src/agg_vcgen_contour.cpp -index ae8f14a..a6a9940 100644 ---- a/src/third_party/agg/src/agg_vcgen_contour.cpp -+++ b/src/third_party/agg/src/agg_vcgen_contour.cpp -@@ -25,16 +25,10 @@ namespace agg - - //------------------------------------------------------------------------ - vcgen_contour::vcgen_contour() : -+ m_stroker(), -+ m_width(1), - m_src_vertices(), - m_out_vertices(), -- m_width(1.0), -- m_line_join(bevel_join), -- m_inner_join(inner_miter), -- m_approx_scale(1.0), -- m_abs_width(1.0), -- m_signed_width(1.0), -- m_miter_limit(4.0), -- m_inner_miter_limit(1.0 + 1.0/64.0), - m_status(initial), - m_src_vertex(0), - m_closed(0), -@@ -43,26 +37,15 @@ namespace agg - { - } - -- - //------------------------------------------------------------------------ - void vcgen_contour::remove_all() - { - m_src_vertices.remove_all(); - m_closed = 0; - m_orientation = 0; -- m_abs_width = fabs(m_width); -- m_signed_width = m_width; - m_status = initial; - } - -- -- //------------------------------------------------------------------------ -- void vcgen_contour::miter_limit_theta(double t) -- { -- m_miter_limit = 1.0 / sin(t * 0.5) ; -- } -- -- - //------------------------------------------------------------------------ - void vcgen_contour::add_vertex(double x, double y, unsigned cmd) - { -@@ -91,14 +74,12 @@ namespace agg - } - } - -- - //------------------------------------------------------------------------ - void vcgen_contour::rewind(unsigned) - { - if(m_status == initial) - { - m_src_vertices.close(true); -- m_signed_width = m_width; - if(m_auto_detect) - { - if(!is_oriented(m_orientation)) -@@ -110,14 +91,13 @@ namespace agg - } - if(is_oriented(m_orientation)) - { -- m_signed_width = is_ccw(m_orientation) ? m_width : -m_width; -+ m_stroker.width(is_ccw(m_orientation) ? m_width : -m_width); - } - } - m_status = ready; - m_src_vertex = 0; - } - -- - //------------------------------------------------------------------------ - unsigned vcgen_contour::vertex(double* x, double* y) - { -@@ -146,18 +126,12 @@ namespace agg - m_status = end_poly; - break; - } -- stroke_calc_join(m_out_vertices, -- m_src_vertices.prev(m_src_vertex), -- m_src_vertices.curr(m_src_vertex), -- m_src_vertices.next(m_src_vertex), -- m_src_vertices.prev(m_src_vertex).dist, -- m_src_vertices.curr(m_src_vertex).dist, -- m_signed_width, -- m_line_join, -- m_inner_join, -- m_miter_limit, -- m_inner_miter_limit, -- m_approx_scale); -+ m_stroker.calc_join(m_out_vertices, -+ m_src_vertices.prev(m_src_vertex), -+ m_src_vertices.curr(m_src_vertex), -+ m_src_vertices.next(m_src_vertex), -+ m_src_vertices.prev(m_src_vertex).dist, -+ m_src_vertices.curr(m_src_vertex).dist); - ++m_src_vertex; - m_status = out_vertices; - m_out_vertex = 0; -diff --git a/src/third_party/agg/src/agg_vcgen_dash.cpp b/src/third_party/agg/src/agg_vcgen_dash.cpp -index 1295057..582b53f 100644 ---- a/src/third_party/agg/src/agg_vcgen_dash.cpp -+++ b/src/third_party/agg/src/agg_vcgen_dash.cpp -@@ -54,7 +54,7 @@ namespace agg - //------------------------------------------------------------------------ - void vcgen_dash::add_dash(double dash_len, double gap_len) - { -- if(m_num_dashes < max_dashes) -+ if(m_num_dashes < max_dashes - 1) - { - m_total_dash_len += dash_len + gap_len; - m_dashes[m_num_dashes++] = dash_len; -diff --git a/src/third_party/agg/src/agg_vcgen_stroke.cpp b/src/third_party/agg/src/agg_vcgen_stroke.cpp -index c505f0f..2dae3e1 100644 ---- a/src/third_party/agg/src/agg_vcgen_stroke.cpp -+++ b/src/third_party/agg/src/agg_vcgen_stroke.cpp -@@ -25,16 +25,10 @@ namespace agg - - //------------------------------------------------------------------------ - vcgen_stroke::vcgen_stroke() : -+ m_stroker(), - m_src_vertices(), - m_out_vertices(), -- m_width(0.5), -- m_miter_limit(4.0), -- m_inner_miter_limit(1.01), -- m_approx_scale(1.0), - m_shorten(0.0), -- 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), -@@ -42,14 +36,6 @@ namespace agg - { - } - -- -- //------------------------------------------------------------------------ -- void vcgen_stroke::miter_limit_theta(double t) -- { -- m_miter_limit = 1.0 / sin(t * 0.5) ; -- } -- -- - //------------------------------------------------------------------------ - void vcgen_stroke::remove_all() - { -@@ -80,22 +66,6 @@ namespace agg - } - } - -- -- //------------------------------------------------------------------------ -- static inline void calc_butt_cap(double* cap, -- const vertex_dist& v0, -- const vertex_dist& v1, -- double len, -- double width) -- { -- double dx = (v1.y - v0.y) * width / len; -- double dy = (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) - { -@@ -135,13 +105,10 @@ namespace agg - break; - - case cap1: -- stroke_calc_cap(m_out_vertices, -- m_src_vertices[0], -- m_src_vertices[1], -- m_src_vertices[0].dist, -- m_line_cap, -- m_width, -- m_approx_scale); -+ m_stroker.calc_cap(m_out_vertices, -+ m_src_vertices[0], -+ m_src_vertices[1], -+ m_src_vertices[0].dist); - m_src_vertex = 1; - m_prev_status = outline1; - m_status = out_vertices; -@@ -149,13 +116,10 @@ namespace agg - break; - - case cap2: -- stroke_calc_cap(m_out_vertices, -- m_src_vertices[m_src_vertices.size() - 1], -- m_src_vertices[m_src_vertices.size() - 2], -- m_src_vertices[m_src_vertices.size() - 2].dist, -- m_line_cap, -- m_width, -- m_approx_scale); -+ m_stroker.calc_cap(m_out_vertices, -+ m_src_vertices[m_src_vertices.size() - 1], -+ m_src_vertices[m_src_vertices.size() - 2], -+ m_src_vertices[m_src_vertices.size() - 2].dist); - m_prev_status = outline2; - m_status = out_vertices; - m_out_vertex = 0; -@@ -179,18 +143,12 @@ namespace agg - break; - } - } -- stroke_calc_join(m_out_vertices, -- m_src_vertices.prev(m_src_vertex), -- m_src_vertices.curr(m_src_vertex), -- m_src_vertices.next(m_src_vertex), -- m_src_vertices.prev(m_src_vertex).dist, -- m_src_vertices.curr(m_src_vertex).dist, -- m_width, -- m_line_join, -- m_inner_join, -- m_miter_limit, -- m_inner_miter_limit, -- m_approx_scale); -+ m_stroker.calc_join(m_out_vertices, -+ m_src_vertices.prev(m_src_vertex), -+ m_src_vertices.curr(m_src_vertex), -+ m_src_vertices.next(m_src_vertex), -+ m_src_vertices.prev(m_src_vertex).dist, -+ m_src_vertices.curr(m_src_vertex).dist); - ++m_src_vertex; - m_prev_status = m_status; - m_status = out_vertices; -@@ -210,18 +168,12 @@ namespace agg - } - - --m_src_vertex; -- stroke_calc_join(m_out_vertices, -- m_src_vertices.next(m_src_vertex), -- m_src_vertices.curr(m_src_vertex), -- m_src_vertices.prev(m_src_vertex), -- m_src_vertices.curr(m_src_vertex).dist, -- m_src_vertices.prev(m_src_vertex).dist, -- m_width, -- m_line_join, -- m_inner_join, -- m_miter_limit, -- m_inner_miter_limit, -- m_approx_scale); -+ m_stroker.calc_join(m_out_vertices, -+ m_src_vertices.next(m_src_vertex), -+ m_src_vertices.curr(m_src_vertex), -+ m_src_vertices.prev(m_src_vertex), -+ m_src_vertices.curr(m_src_vertex).dist, -+ m_src_vertices.prev(m_src_vertex).dist); - - m_prev_status = m_status; - m_status = out_vertices; -diff --git a/src/third_party/agg/src/agg_vpgen_clip_polyline.cpp b/src/third_party/agg/src/agg_vpgen_clip_polyline.cpp -index 36d1247..6840803 100644 ---- a/src/third_party/agg/src/agg_vpgen_clip_polyline.cpp -+++ b/src/third_party/agg/src/agg_vpgen_clip_polyline.cpp -@@ -13,19 +13,17 @@ - // http://www.antigrain.com - //---------------------------------------------------------------------------- - --#include - #include "agg_vpgen_clip_polyline.h" -+#include "agg_clip_liang_barsky.h" - - namespace agg - { -- static double clip_epsilon = 1e-10; -- -- - //---------------------------------------------------------------------------- - void vpgen_clip_polyline::reset() - { - m_vertex = 0; - m_num_vertices = 0; -+ m_move_to = false; - } - - //---------------------------------------------------------------------------- -@@ -33,99 +31,38 @@ namespace agg - { - m_vertex = 0; - m_num_vertices = 0; -- m_f1 = clipping_flags(x, y); -- if(m_f1 == 0) -- { -- m_x[0] = x; -- m_y[0] = y; -- m_cmd[0] = path_cmd_move_to; -- m_num_vertices = 1; -- } - m_x1 = x; - m_y1 = y; -+ m_move_to = true; - } - -- - //---------------------------------------------------------------------------- -- bool vpgen_clip_polyline::move_point(double& x, double& y, unsigned& flags) -+ void vpgen_clip_polyline::line_to(double x, double y) - { -- double bound; -- -- if(flags & (clip_x1 | clip_x2)) -- { -- bound = (flags & clip_x1) ? m_clip_box.x1 : m_clip_box.x2; -- y = (bound - m_x1) * (m_y2 - m_y1) / (m_x2 - m_x1) + m_y1; -- x = bound; -- flags = clipping_flags_y(y); -- } -- if(fabs(m_y2 - m_y1) < clip_epsilon && fabs(m_x2 - m_x1) < clip_epsilon) -- { -- return false; -- } -- if(flags & (clip_y1 | clip_y2)) -- { -- bound = (flags & clip_y1) ? m_clip_box.y1 : m_clip_box.y2; -- x = (bound - m_y1) * (m_x2 - m_x1) / (m_y2 - m_y1) + m_x1; -- y = bound; -- } -- flags = 0; -- return true; -- } -+ double x2 = x; -+ double y2 = y; -+ unsigned flags = clip_line_segment(&m_x1, &m_y1, &x2, &y2, m_clip_box); - -- //---------------------------------------------------------------------------- -- void vpgen_clip_polyline::clip_line_segment() -- { -- if((m_f1 & m_f2) == 0) -+ m_vertex = 0; -+ m_num_vertices = 0; -+ if((flags & 4) == 0) - { -- if(m_f1) -- { -- if(!move_point(m_x1, m_y1, m_f1)) return; -- if(m_f1) return; -+ if((flags & 1) != 0 || m_move_to) -+ { - m_x[0] = m_x1; - m_y[0] = m_y1; - m_cmd[0] = path_cmd_move_to; - m_num_vertices = 1; - } -- if(m_f2) -- { // Move Point 2 -- if(!move_point(m_x2, m_y2, m_f2)) return; -- } -- m_x[m_num_vertices] = m_x2; -- m_y[m_num_vertices] = m_y2; -+ m_x[m_num_vertices] = x2; -+ m_y[m_num_vertices] = y2; - m_cmd[m_num_vertices++] = path_cmd_line_to; -+ m_move_to = (flags & 2) != 0; - } -- } -- -- -- -- //---------------------------------------------------------------------------- -- void vpgen_clip_polyline::line_to(double x, double y) -- { -- m_vertex = 0; -- m_num_vertices = 0; -- unsigned f = m_f2 = clipping_flags(m_x2 = x, m_y2 = y); -- -- if(m_f2 == m_f1) -- { -- if(m_f2 == 0) -- { -- m_x[0] = x; -- m_y[0] = y; -- m_cmd[0] = path_cmd_line_to; -- m_num_vertices = 1; -- } -- } -- else -- { -- clip_line_segment(); -- } -- -- m_f1 = f; - m_x1 = x; - m_y1 = y; - } - -- - //---------------------------------------------------------------------------- - unsigned vpgen_clip_polyline::vertex(double* x, double* y) - { -@@ -137,6 +74,4 @@ namespace agg - } - return path_cmd_stop; - } -- -- - } --- -2.19.0 -