diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 572af70ad..b38ae3665 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,7 +1,6 @@
 project(Slic3r-native)
 
 add_subdirectory(admesh)
-add_subdirectory(agg_svg)
 add_subdirectory(avrdude)
 # boost/nowide
 add_subdirectory(boost)
diff --git a/src/agg/AUTHORS b/src/agg/AUTHORS
index c0c4ea344..2bb6518ec 100644
--- a/src/agg/AUTHORS
+++ b/src/agg/AUTHORS
@@ -1,3 +1,2 @@
-Anti-Grain Geometry (AGG) - Version 2.5
-A high quality rendering engine for C++
-Copyright (C) 2002-2006 Maxim Shemanarev
+Anti-Grain Geometry - Version 2.4
+Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) 
diff --git a/src/agg/README b/src/agg/README
deleted file mode 100644
index 28420a850..000000000
--- a/src/agg/README
+++ /dev/null
@@ -1,21 +0,0 @@
-Anti-Grain Geometry (AGG) - Version 2.5
-A high quality rendering engine for C++
-Copyright (C) 2002-2006 Maxim Shemanarev
-Contact: mcseem@antigrain.com
-         mcseemagg@yahoo.com
-         http://antigrain.com
-
-AGG is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-AGG is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with AGG; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-MA 02110-1301, USA.
\ No newline at end of file
diff --git a/src/agg/VERSION b/src/agg/VERSION
new file mode 100644
index 000000000..c5de3e3b0
--- /dev/null
+++ b/src/agg/VERSION
@@ -0,0 +1,2 @@
+2.4
+svn revision 128
\ No newline at end of file
diff --git a/src/agg/agg_array.h b/src/agg/agg_array.h
index 5c6d390bf..8d5668384 100644
--- a/src/agg/agg_array.h
+++ b/src/agg/agg_array.h
@@ -1,27 +1,17 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
-
 #ifndef AGG_ARRAY_INCLUDED
 #define AGG_ARRAY_INCLUDED
 
diff --git a/src/agg/agg_basics.h b/src/agg/agg_basics.h
index 4a1b481fc..273850ba1 100644
--- a/src/agg/agg_basics.h
+++ b/src/agg/agg_basics.h
@@ -1,31 +1,22 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
 
 #ifndef AGG_BASICS_INCLUDED
 #define AGG_BASICS_INCLUDED
 
-#include <math.h>
+#include <cmath>
 #include "agg_config.h"
 
 //---------------------------------------------------------AGG_CUSTOM_ALLOCATOR
@@ -152,10 +143,18 @@ namespace agg
         __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));
@@ -169,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));
@@ -186,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));
@@ -212,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;
         }
     };
@@ -238,7 +254,7 @@ namespace agg
     {
         poly_subpixel_shift = 8,                      //----poly_subpixel_shift
         poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale 
-        poly_subpixel_mask  = poly_subpixel_scale-1,  //----poly_subpixel_mask 
+        poly_subpixel_mask  = poly_subpixel_scale-1   //----poly_subpixel_mask 
     };
 
     //----------------------------------------------------------filling_rule_e
@@ -305,6 +321,12 @@ namespace agg
         {
             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
@@ -529,9 +551,22 @@ namespace agg
     //------------------------------------------------------------is_equal_eps
     template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon)
     {
-        return fabs(v1 - v2) <= double(epsilon);
-    }
+	bool neg1 = v1 < 0.0;
+	bool neg2 = v2 < 0.0;
 
+	if (neg1 != neg2)
+	    return std::fabs(v1) < epsilon && std::fabs(v2) < epsilon;
+
+        int int1, int2;
+	std::frexp(v1, &int1);
+	std::frexp(v2, &int2);
+	int min12 = int1 < int2 ? int1 : int2;
+
+	v1 = std::ldexp(v1, -min12);
+	v2 = std::ldexp(v2, -min12);
+
+	return std::fabs(v1 - v2) < epsilon;
+    }
 }
 
 
diff --git a/src/agg/agg_bezier_arc.h b/src/agg/agg_bezier_arc.h
index a6f2b2221..cfd9308ea 100644
--- a/src/agg/agg_bezier_arc.h
+++ b/src/agg/agg_bezier_arc.h
@@ -1,25 +1,21 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e., 
+// 4, 7, 10, or 13 vertices.
+//
 //----------------------------------------------------------------------------
 
 #ifndef AGG_BEZIER_ARC_INCLUDED
@@ -72,7 +68,7 @@ namespace agg
             *x = m_vertices[m_vertex];
             *y = m_vertices[m_vertex + 1];
             m_vertex += 2;
-            return (m_vertex == 2) ? path_cmd_move_to : m_cmd;
+            return (m_vertex == 2) ? unsigned(path_cmd_move_to) : m_cmd;
         }
 
         // Supplemantary functions. num_vertices() actually returns doubled 
diff --git a/src/agg/agg_bounding_rect.h b/src/agg/agg_bounding_rect.h
deleted file mode 100644
index e82c181b2..000000000
--- a/src/agg/agg_bounding_rect.h
+++ /dev/null
@@ -1,122 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_BOUNDING_RECT_INCLUDED
-#define AGG_BOUNDING_RECT_INCLUDED
-
-#include "agg_basics.h"
-
-namespace agg
-{
-
-    //-----------------------------------------------------------bounding_rect
-    template<class VertexSource, class GetId, class CoordT>
-    bool bounding_rect(VertexSource& vs, GetId& gi, 
-                       unsigned start, unsigned num, 
-                       CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
-    {
-        unsigned i;
-        double x;
-        double y;
-        bool first = true;
-
-        *x1 = CoordT(1);
-        *y1 = CoordT(1);
-        *x2 = CoordT(0);
-        *y2 = CoordT(0);
-
-        for(i = 0; i < num; i++)
-        {
-            vs.rewind(gi[start + i]);
-            unsigned cmd;
-            while(!is_stop(cmd = vs.vertex(&x, &y)))
-            {
-                if(is_vertex(cmd))
-                {
-                    if(first)
-                    {
-                        *x1 = CoordT(x);
-                        *y1 = CoordT(y);
-                        *x2 = CoordT(x);
-                        *y2 = CoordT(y);
-                        first = false;
-                    }
-                    else
-                    {
-                        if(CoordT(x) < *x1) *x1 = CoordT(x);
-                        if(CoordT(y) < *y1) *y1 = CoordT(y);
-                        if(CoordT(x) > *x2) *x2 = CoordT(x);
-                        if(CoordT(y) > *y2) *y2 = CoordT(y);
-                    }
-                }
-            }
-        }
-        return *x1 <= *x2 && *y1 <= *y2;
-    }
-
-
-    //-----------------------------------------------------bounding_rect_single
-    template<class VertexSource, class CoordT> 
-    bool bounding_rect_single(VertexSource& vs, unsigned path_id,
-                              CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
-    {
-        double x;
-        double y;
-        bool first = true;
-
-        *x1 = CoordT(1);
-        *y1 = CoordT(1);
-        *x2 = CoordT(0);
-        *y2 = CoordT(0);
-
-        vs.rewind(path_id);
-        unsigned cmd;
-        while(!is_stop(cmd = vs.vertex(&x, &y)))
-        {
-            if(is_vertex(cmd))
-            {
-                if(first)
-                {
-                    *x1 = CoordT(x);
-                    *y1 = CoordT(y);
-                    *x2 = CoordT(x);
-                    *y2 = CoordT(y);
-                    first = false;
-                }
-                else
-                {
-                    if(CoordT(x) < *x1) *x1 = CoordT(x);
-                    if(CoordT(y) < *y1) *y1 = CoordT(y);
-                    if(CoordT(x) > *x2) *x2 = CoordT(x);
-                    if(CoordT(y) > *y2) *y2 = CoordT(y);
-                }
-            }
-        }
-        return *x1 <= *x2 && *y1 <= *y2;
-    }
-
-
-}
-
-#endif
diff --git a/src/agg/agg_clip_liang_barsky.h b/src/agg/agg_clip_liang_barsky.h
index e89756024..4b5fedbab 100644
--- a/src/agg/agg_clip_liang_barsky.h
+++ b/src/agg/agg_clip_liang_barsky.h
@@ -1,27 +1,21 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// Liang-Barsky clipping 
+//
 //----------------------------------------------------------------------------
-
 #ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED
 #define AGG_CLIP_LIANG_BARSKY_INCLUDED
 
diff --git a/src/agg/agg_color_gray.h b/src/agg/agg_color_gray.h
index a4d50e8a3..f66588c11 100644
--- a/src/agg/agg_color_gray.h
+++ b/src/agg/agg_color_gray.h
@@ -1,25 +1,16 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
 //
 // Adaptation for high precision colors has been sponsored by 
@@ -44,7 +35,8 @@ namespace agg
 {
 
     //===================================================================gray8
-    struct gray8
+    template<class Colorspace>
+    struct gray8T
     {
         typedef int8u  value_type;
         typedef int32u calc_type;
@@ -53,63 +45,295 @@ namespace agg
         {
             base_shift = 8,
             base_scale = 1 << base_shift,
-            base_mask  = base_scale - 1
+            base_mask  = base_scale - 1,
+            base_MSB = 1 << (base_shift - 1)
         };
-        typedef gray8 self_type;
+        typedef gray8T self_type;
 
         value_type v;
         value_type a;
 
-        //--------------------------------------------------------------------
-        gray8() {}
-
-        //--------------------------------------------------------------------
-        gray8(unsigned v_, unsigned a_=base_mask) :
-            v(int8u(v_)), a(int8u(a_)) {}
-
-        //--------------------------------------------------------------------
-        gray8(const self_type& c, unsigned a_) :
-            v(c.v), a(value_type(a_)) {}
-
-        //--------------------------------------------------------------------
-        gray8(const rgba& c) :
-            v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
-            a((value_type)uround(c.a * double(base_mask))) {}
-
-        //--------------------------------------------------------------------
-        gray8(const rgba& c, double a_) :
-            v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
-            a((value_type)uround(a_ * double(base_mask))) {}
-
-        //--------------------------------------------------------------------
-        gray8(const rgba8& c) :
-            v((c.r*77 + c.g*150 + c.b*29) >> 8),
-            a(c.a) {}
-
-        //--------------------------------------------------------------------
-        gray8(const rgba8& c, unsigned a_) :
-            v((c.r*77 + c.g*150 + c.b*29) >> 8),
-            a(a_) {}
-
-        //--------------------------------------------------------------------
-        void clear()
+        static value_type luminance(const rgba& c)
         {
-            v = a = 0;
+            // Calculate grayscale value as per ITU-R BT.709.
+            return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask));
+        }
+
+        static value_type luminance(const rgba8& c)
+        {
+            // Calculate grayscale value as per ITU-R BT.709.
+            return value_type((55u * c.r + 184u * c.g + 18u * c.b) >> 8);
+        }
+
+        static void convert(gray8T<linear>& dst, const gray8T<sRGB>& src)
+        {
+            dst.v = sRGB_conv<value_type>::rgb_from_sRGB(src.v);
+            dst.a = src.a;
+        }
+
+        static void convert(gray8T<sRGB>& dst, const gray8T<linear>& src)
+        {
+            dst.v = sRGB_conv<value_type>::rgb_to_sRGB(src.v);
+            dst.a = src.a;
+        }
+
+        static void convert(gray8T<linear>& dst, const rgba8& src)
+        {
+            dst.v = luminance(src);
+            dst.a = src.a;
+        }
+
+        static void convert(gray8T<linear>& dst, const srgba8& src)
+        {
+            // The RGB weights are only valid for linear values.
+            convert(dst, rgba8(src));
+        }
+
+        static void convert(gray8T<sRGB>& dst, const rgba8& src)
+        {
+            dst.v = sRGB_conv<value_type>::rgb_to_sRGB(luminance(src));
+            dst.a = src.a;
+        }
+
+        static void convert(gray8T<sRGB>& dst, const srgba8& src)
+        {
+            // The RGB weights are only valid for linear values.
+            convert(dst, rgba8(src));
         }
 
         //--------------------------------------------------------------------
-        const self_type& transparent()
+        gray8T() {}
+
+        //--------------------------------------------------------------------
+        explicit gray8T(unsigned v_, unsigned a_ = base_mask) :
+            v(int8u(v_)), a(int8u(a_)) {}
+
+        //--------------------------------------------------------------------
+        gray8T(const self_type& c, unsigned a_) :
+            v(c.v), a(value_type(a_)) {}
+
+        //--------------------------------------------------------------------
+        gray8T(const rgba& c) :
+            v(luminance(c)),
+            a(value_type(uround(c.a * base_mask))) {}
+
+        //--------------------------------------------------------------------
+        template<class T>
+        gray8T(const gray8T<T>& c)
+        {
+            convert(*this, c);
+        }
+
+        //--------------------------------------------------------------------
+        template<class T>
+        gray8T(const rgba8T<T>& c)
+        {
+            convert(*this, c);
+        }
+
+        //--------------------------------------------------------------------
+        template<class T> 
+        T convert_from_sRGB() const 
+        {
+            typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_from_sRGB(v);
+            return T(y, y, y, sRGB_conv<typename T::value_type>::alpha_from_sRGB(a));
+        }
+
+        template<class T> 
+        T convert_to_sRGB() const 
+        {
+            typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_to_sRGB(v);
+            return T(y, y, y, sRGB_conv<typename T::value_type>::alpha_to_sRGB(a));
+        }
+
+        //--------------------------------------------------------------------
+        rgba8 make_rgba8(const linear&) const 
+        {
+            return rgba8(v, v, v, a);
+        }
+
+        rgba8 make_rgba8(const sRGB&) const 
+        {
+            return convert_from_sRGB<srgba8>();
+        }
+
+        operator rgba8() const 
+        {
+            return make_rgba8(Colorspace());
+        }
+
+        //--------------------------------------------------------------------
+        srgba8 make_srgba8(const linear&) const 
+        {
+            return convert_to_sRGB<rgba8>();
+        }
+
+        srgba8 make_srgba8(const sRGB&) const 
+        {
+            return srgba8(v, v, v, a);
+        }
+
+        operator srgba8() const 
+        {
+            return make_rgba8(Colorspace());
+        }
+
+        //--------------------------------------------------------------------
+        rgba16 make_rgba16(const linear&) const 
+        {
+            rgba16::value_type rgb = (v << 8) | v;
+            return rgba16(rgb, rgb, rgb, (a << 8) | a);
+        }
+
+        rgba16 make_rgba16(const sRGB&) const 
+        {
+            return convert_from_sRGB<rgba16>();
+        }
+
+        operator rgba16() const 
+        {
+            return make_rgba16(Colorspace());
+        }
+
+        //--------------------------------------------------------------------
+        rgba32 make_rgba32(const linear&) const 
+        {
+            rgba32::value_type v32 = v / 255.0f;
+            return rgba32(v32, v32, v32, a / 255.0f);
+        }
+
+        rgba32 make_rgba32(const sRGB&) const 
+        {
+            return convert_from_sRGB<rgba32>();
+        }
+
+        operator rgba32() const 
+        {
+            return make_rgba32(Colorspace());
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE double to_double(value_type a)
+        {
+            return double(a) / base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type from_double(double a)
+        {
+            return value_type(uround(a * base_mask));
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type empty_value()
+        {
+            return 0;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type full_value()
+        {
+            return base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_transparent() const
+        {
+            return a == 0;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_opaque() const
+        {
+            return a == base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        // Fixed-point multiply, exact over int8u.
+        static AGG_INLINE value_type multiply(value_type a, value_type b) 
+        {
+            calc_type t = a * b + base_MSB;
+            return value_type(((t >> base_shift) + t) >> base_shift);
+        }
+        
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type demultiply(value_type a, value_type b) 
+        {
+            if (a * b == 0)
+            {
+                return 0;
+            }
+            else if (a >= b)
+            {
+                return base_mask;
+            }
+            else return value_type((a * base_mask + (b >> 1)) / b); 
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downscale(T a) 
+        {
+            return a >> base_shift;
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downshift(T a, unsigned n) 
+        {
+            return a >> n;
+        }
+
+        //--------------------------------------------------------------------
+        // Fixed-point multiply, exact over int8u.
+        // Specifically for multiplying a color component by a cover.
+        static AGG_INLINE value_type mult_cover(value_type a, value_type b) 
+        {
+            return multiply(a, b);
+        }
+        
+        //--------------------------------------------------------------------
+        static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) 
+        {
+            return multiply(b, a);
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a, assuming q is premultiplied by a.
+        static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) 
+        {
+            return p + q - multiply(p, a);
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a.
+        static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) 
+        {
+            int t = (q - p) * a + base_MSB - (p > q);
+            return value_type(p + (((t >> base_shift) + t) >> base_shift));
+        }
+        
+        //--------------------------------------------------------------------
+        self_type& clear()
+        {
+            v = a = 0;
+			return *this;
+        }
+
+        //--------------------------------------------------------------------
+        self_type& transparent()
         {
             a = 0;
             return *this;
         }
 
         //--------------------------------------------------------------------
-        void opacity(double a_)
+        self_type& opacity(double a_)
         {
-            if(a_ < 0.0) a_ = 0.0;
-            if(a_ > 1.0) a_ = 1.0;
-            a = (value_type)uround(a_ * double(base_mask));
+            if (a_ < 0) a = 0;
+            else if (a_ > 1) a = 1;
+            else a = (value_type)uround(a_ * double(base_mask));
+			return *this;
         }
 
         //--------------------------------------------------------------------
@@ -117,47 +341,33 @@ namespace agg
         {
             return double(a) / double(base_mask);
         }
-
-
+        
         //--------------------------------------------------------------------
-        const self_type& premultiply()
+        self_type& premultiply()
         {
-            if(a == base_mask) return *this;
-            if(a == 0)
+            if (a < base_mask)
             {
-                v = 0;
-                return *this;
+                if (a == 0) v = 0;
+                else v = multiply(v, a);
             }
-            v = value_type((calc_type(v) * a) >> base_shift);
             return *this;
         }
 
         //--------------------------------------------------------------------
-        const self_type& premultiply(unsigned a_)
+        self_type& demultiply()
         {
-            if(a == base_mask && a_ >= base_mask) return *this;
-            if(a == 0 || a_ == 0)
+            if (a < base_mask)
             {
-                v = a = 0;
-                return *this;
+                if (a == 0)
+                {
+                    v = 0;
+                }
+                else
+                {
+                    calc_type v_ = (calc_type(v) * base_mask) / a;
+                    v = value_type((v_ > base_mask) ? (value_type)base_mask : v_);
+                }
             }
-            calc_type v_ = (calc_type(v) * a_) / a;
-            v = value_type((v_ > a_) ? a_ : v_);
-            a = value_type(a_);
-            return *this;
-        }
-
-        //--------------------------------------------------------------------
-        const self_type& demultiply()
-        {
-            if(a == base_mask) return *this;
-            if(a == 0)
-            {
-                v = 0;
-                return *this;
-            }
-            calc_type v_ = (calc_type(v) * base_mask) / a;
-            v = value_type((v_ > base_mask) ? (value_type)base_mask : v_);
             return *this;
         }
 
@@ -166,8 +376,8 @@ namespace agg
         {
             self_type ret;
             calc_type ik = uround(k * base_scale);
-            ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
-            ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
+            ret.v = lerp(v, c.v, ik);
+            ret.a = lerp(a, c.a, ik);
             return ret;
         }
 
@@ -175,59 +385,34 @@ namespace agg
         AGG_INLINE void add(const self_type& c, unsigned cover)
         {
             calc_type cv, ca;
-            if(cover == cover_mask)
+            if (cover == cover_mask)
             {
-                if(c.a == base_mask) 
+                if (c.a == base_mask) 
                 {
                     *this = c;
+                    return;
                 }
                 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;
+                    cv = v + c.v; 
+                    ca = a + c.a; 
                 }
             }
             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;
+                cv = v + mult_cover(c.v, cover);
+                ca = a + mult_cover(c.a, cover);
             }
+            v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv);
+            a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
         }
 
         //--------------------------------------------------------------------
         static self_type no_color() { return self_type(0,0); }
     };
 
-
-    //-------------------------------------------------------------gray8_pre
-    inline gray8 gray8_pre(unsigned v, unsigned a = gray8::base_mask)
-    {
-        return gray8(v,a).premultiply();
-    }
-    inline gray8 gray8_pre(const gray8& c, unsigned a)
-    {
-        return gray8(c,a).premultiply();
-    }
-    inline gray8 gray8_pre(const rgba& c)
-    {
-        return gray8(c).premultiply();
-    }
-    inline gray8 gray8_pre(const rgba& c, double a)
-    {
-        return gray8(c,a).premultiply();
-    }
-    inline gray8 gray8_pre(const rgba8& c)
-    {
-        return gray8(c).premultiply();
-    }
-    inline gray8 gray8_pre(const rgba8& c, unsigned a)
-    {
-        return gray8(c,a).premultiply();
-    }
-
-
+    typedef gray8T<linear> gray8;
+    typedef gray8T<sRGB> sgray8;
 
 
     //==================================================================gray16
@@ -240,18 +425,46 @@ namespace agg
         {
             base_shift = 16,
             base_scale = 1 << base_shift,
-            base_mask  = base_scale - 1
+            base_mask  = base_scale - 1,
+            base_MSB = 1 << (base_shift - 1)
         };
         typedef gray16 self_type;
 
         value_type v;
         value_type a;
 
+        static value_type luminance(const rgba& c)
+        {
+            // Calculate grayscale value as per ITU-R BT.709.
+            return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask));
+        }
+
+        static value_type luminance(const rgba16& c)
+        {
+            // Calculate grayscale value as per ITU-R BT.709.
+            return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16);
+        }
+
+        static value_type luminance(const rgba8& c)
+        {
+            return luminance(rgba16(c));
+        }
+
+        static value_type luminance(const srgba8& c)
+        {
+            return luminance(rgba16(c));
+        }
+
+        static value_type luminance(const rgba32& c)
+        {
+            return luminance(rgba(c));
+        }
+
         //--------------------------------------------------------------------
         gray16() {}
 
         //--------------------------------------------------------------------
-        gray16(unsigned v_, unsigned a_=base_mask) :
+        explicit gray16(unsigned v_, unsigned a_ = base_mask) :
             v(int16u(v_)), a(int16u(a_)) {}
 
         //--------------------------------------------------------------------
@@ -260,43 +473,196 @@ namespace agg
 
         //--------------------------------------------------------------------
         gray16(const rgba& c) :
-            v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
+            v(luminance(c)),
             a((value_type)uround(c.a * double(base_mask))) {}
 
-        //--------------------------------------------------------------------
-        gray16(const rgba& c, double a_) :
-            v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
-            a((value_type)uround(a_ * double(base_mask))) {}
-
         //--------------------------------------------------------------------
         gray16(const rgba8& c) :
-            v(c.r*77 + c.g*150 + c.b*29),
+            v(luminance(c)),
             a((value_type(c.a) << 8) | c.a) {}
 
         //--------------------------------------------------------------------
-        gray16(const rgba8& c, unsigned a_) :
-            v(c.r*77 + c.g*150 + c.b*29),
-            a((value_type(a_) << 8) | c.a) {}
+        gray16(const srgba8& c) :
+            v(luminance(c)),
+            a((value_type(c.a) << 8) | c.a) {}
 
         //--------------------------------------------------------------------
-        void clear()
+        gray16(const rgba16& c) :
+            v(luminance(c)),
+            a(c.a) {}
+        
+        //--------------------------------------------------------------------
+        gray16(const gray8& c) :
+            v((value_type(c.v) << 8) | c.v),
+            a((value_type(c.a) << 8) | c.a) {}
+
+        //--------------------------------------------------------------------
+        gray16(const sgray8& c) :
+            v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)),
+            a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
+
+        //--------------------------------------------------------------------
+        operator rgba8() const 
         {
-            v = a = 0;
+            return rgba8(v >> 8, v >> 8, v >> 8, a >> 8);
         }
 
         //--------------------------------------------------------------------
-        const self_type& transparent()
+        operator srgba8() const 
+        {
+            value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v);
+            return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a));
+        }
+
+        //--------------------------------------------------------------------
+        operator rgba16() const 
+        {
+            return rgba16(v, v, v, a);
+        }
+
+		//--------------------------------------------------------------------
+		operator rgba32() const
+		{
+			rgba32::value_type v32 = v / 65535.0f;
+			return rgba32(v32, v32, v32, a / 65535.0f);
+		}
+
+		//--------------------------------------------------------------------
+        operator gray8() const 
+        {
+            return gray8(v >> 8, a >> 8);
+        }
+
+        //--------------------------------------------------------------------
+        operator sgray8() const 
+        {
+            return sgray8(
+                sRGB_conv<value_type>::rgb_to_sRGB(v), 
+                sRGB_conv<value_type>::alpha_to_sRGB(a));
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE double to_double(value_type a)
+        {
+            return double(a) / base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type from_double(double a)
+        {
+            return value_type(uround(a * base_mask));
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type empty_value()
+        {
+            return 0;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type full_value()
+        {
+            return base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_transparent() const
+        {
+            return a == 0;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_opaque() const
+        {
+            return a == base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        // Fixed-point multiply, exact over int16u.
+        static AGG_INLINE value_type multiply(value_type a, value_type b) 
+        {
+            calc_type t = a * b + base_MSB;
+            return value_type(((t >> base_shift) + t) >> base_shift);
+        }
+        
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type demultiply(value_type a, value_type b) 
+        {
+            if (a * b == 0)
+            {
+                return 0;
+            }
+            else if (a >= b)
+            {
+                return base_mask;
+            }
+            else return value_type((a * base_mask + (b >> 1)) / b); 
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downscale(T a) 
+        {
+            return a >> base_shift;
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downshift(T a, unsigned n) 
+        {
+            return a >> n;
+        }
+
+        //--------------------------------------------------------------------
+        // Fixed-point multiply, almost exact over int16u.
+        // Specifically for multiplying a color component by a cover.
+        static AGG_INLINE value_type mult_cover(value_type a, cover_type b) 
+        {
+            return multiply(a, b << 8 | b);
+        }
+        
+        //--------------------------------------------------------------------
+        static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) 
+        {
+            return mult_cover(b, a) >> 8;
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a, assuming q is premultiplied by a.
+        static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) 
+        {
+            return p + q - multiply(p, a);
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a.
+        static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) 
+        {
+            int t = (q - p) * a + base_MSB - (p > q);
+            return value_type(p + (((t >> base_shift) + t) >> base_shift));
+        }
+        
+        //--------------------------------------------------------------------
+        self_type& clear()
+        {
+            v = a = 0;
+			return *this;
+        }
+
+        //--------------------------------------------------------------------
+        self_type& transparent()
         {
             a = 0;
             return *this;
         }
 
         //--------------------------------------------------------------------
-        void opacity(double a_)
+        self_type& opacity(double a_)
         {
-            if(a_ < 0.0) a_ = 0.0;
-            if(a_ > 1.0) a_ = 1.0;
-            a = (value_type)uround(a_ * double(base_mask));
+            if (a_ < 0) a = 0;
+            else if(a_ > 1) a = 1;
+            else a = (value_type)uround(a_ * double(base_mask));
+			return *this;
         }
 
         //--------------------------------------------------------------------
@@ -307,44 +673,31 @@ namespace agg
 
 
         //--------------------------------------------------------------------
-        const self_type& premultiply()
+        self_type& premultiply()
         {
-            if(a == base_mask) return *this;
-            if(a == 0)
+            if (a < base_mask)
             {
-                v = 0;
-                return *this;
+                if(a == 0) v = 0;
+                else v = multiply(v, a);
             }
-            v = value_type((calc_type(v) * a) >> base_shift);
             return *this;
         }
 
         //--------------------------------------------------------------------
-        const self_type& premultiply(unsigned a_)
+        self_type& demultiply()
         {
-            if(a == base_mask && a_ >= base_mask) return *this;
-            if(a == 0 || a_ == 0)
+            if (a < base_mask)
             {
-                v = a = 0;
-                return *this;
+                if (a == 0)
+                {
+                    v = 0;
+                }
+                else
+                {
+                    calc_type v_ = (calc_type(v) * base_mask) / a;
+					v = (v_ > base_mask) ? value_type(base_mask) : value_type(v_);
+                }
             }
-            calc_type v_ = (calc_type(v) * a_) / a;
-            v = value_type((v_ > a_) ? a_ : v_);
-            a = value_type(a_);
-            return *this;
-        }
-
-        //--------------------------------------------------------------------
-        const self_type& demultiply()
-        {
-            if(a == base_mask) return *this;
-            if(a == 0)
-            {
-                v = 0;
-                return *this;
-            }
-            calc_type v_ = (calc_type(v) * base_mask) / a;
-            v = value_type((v_ > base_mask) ? base_mask : v_);
             return *this;
         }
 
@@ -353,8 +706,8 @@ namespace agg
         {
             self_type ret;
             calc_type ik = uround(k * base_scale);
-            ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
-            ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
+            ret.v = lerp(v, c.v, ik);
+            ret.a = lerp(a, c.a, ik);
             return ret;
         }
 
@@ -362,25 +715,26 @@ namespace agg
         AGG_INLINE void add(const self_type& c, unsigned cover)
         {
             calc_type cv, ca;
-            if(cover == cover_mask)
+            if (cover == cover_mask)
             {
-                if(c.a == base_mask) 
+                if (c.a == base_mask) 
                 {
                     *this = c;
+                    return;
                 }
                 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;
+                    cv = v + c.v; 
+                    ca = a + c.a; 
                 }
             }
             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;
+                cv = v + mult_cover(c.v, cover);
+                ca = a + mult_cover(c.a, cover);
             }
+            v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv);
+            a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
         }
 
         //--------------------------------------------------------------------
@@ -388,33 +742,303 @@ namespace agg
     };
 
 
-    //------------------------------------------------------------gray16_pre
-    inline gray16 gray16_pre(unsigned v, unsigned a = gray16::base_mask)
+    //===================================================================gray32
+    struct gray32
     {
-        return gray16(v,a).premultiply();
-    }
-    inline gray16 gray16_pre(const gray16& c, unsigned a)
-    {
-        return gray16(c,a).premultiply();
-    }
-    inline gray16 gray16_pre(const rgba& c)
-    {
-        return gray16(c).premultiply();
-    }
-    inline gray16 gray16_pre(const rgba& c, double a)
-    {
-        return gray16(c,a).premultiply();
-    }
-    inline gray16 gray16_pre(const rgba8& c)
-    {
-        return gray16(c).premultiply();
-    }
-    inline gray16 gray16_pre(const rgba8& c, unsigned a)
-    {
-        return gray16(c,a).premultiply();
-    }
+        typedef float value_type;
+        typedef double calc_type;
+        typedef double long_type;
+        typedef gray32 self_type;
+
+        value_type v;
+        value_type a;
+
+        // Calculate grayscale value as per ITU-R BT.709.
+        static value_type luminance(double r, double g, double b)
+        {
+            return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b);
+        }
+
+        static value_type luminance(const rgba& c)
+        {
+            return luminance(c.r, c.g, c.b);
+        }
+
+        static value_type luminance(const rgba32& c)
+        {
+            return luminance(c.r, c.g, c.b);
+        }
+
+        static value_type luminance(const rgba8& c)
+        {
+            return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0);
+        }
+
+        static value_type luminance(const rgba16& c)
+        {
+            return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0);
+        }
+
+        //--------------------------------------------------------------------
+        gray32() {}
+
+        //--------------------------------------------------------------------
+        explicit gray32(value_type v_, value_type a_ = 1) :
+            v(v_), a(a_) {}
+
+        //--------------------------------------------------------------------
+        gray32(const self_type& c, value_type a_) :
+            v(c.v), a(a_) {}
+
+        //--------------------------------------------------------------------
+        gray32(const rgba& c) :
+            v(luminance(c)),
+            a(value_type(c.a)) {}
+
+        //--------------------------------------------------------------------
+        gray32(const rgba8& c) :
+            v(luminance(c)),
+            a(value_type(c.a / 255.0)) {}
+
+        //--------------------------------------------------------------------
+        gray32(const srgba8& c) :
+            v(luminance(rgba32(c))),
+            a(value_type(c.a / 255.0)) {}
+
+        //--------------------------------------------------------------------
+        gray32(const rgba16& c) :
+            v(luminance(c)),
+            a(value_type(c.a / 65535.0)) {}
+
+        //--------------------------------------------------------------------
+        gray32(const rgba32& c) :
+            v(luminance(c)),
+            a(value_type(c.a)) {}
+
+        //--------------------------------------------------------------------
+        gray32(const gray8& c) :
+            v(value_type(c.v / 255.0)), 
+            a(value_type(c.a / 255.0)) {}
+
+        //--------------------------------------------------------------------
+        gray32(const sgray8& c) :
+            v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)), 
+            a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
+
+        //--------------------------------------------------------------------
+        gray32(const gray16& c) :
+            v(value_type(c.v / 65535.0)), 
+            a(value_type(c.a / 65535.0)) {}
+
+        //--------------------------------------------------------------------
+        operator rgba() const 
+        {
+            return rgba(v, v, v, a);
+        }
+
+        //--------------------------------------------------------------------
+        operator gray8() const 
+        {
+            return gray8(uround(v * 255.0), uround(a * 255.0));
+        }
+
+        //--------------------------------------------------------------------
+        operator sgray8() const 
+        {
+            // Return (non-premultiplied) sRGB values.
+            return sgray8(
+                sRGB_conv<value_type>::rgb_to_sRGB(v), 
+                sRGB_conv<value_type>::alpha_to_sRGB(a));
+        }
+
+        //--------------------------------------------------------------------
+        operator gray16() const 
+        {
+            return gray16(uround(v * 65535.0), uround(a * 65535.0));
+        }
+
+        //--------------------------------------------------------------------
+        operator rgba8() const 
+        {
+            rgba8::value_type y = uround(v * 255.0);
+            return rgba8(y, y, y, uround(a * 255.0));
+        }
+
+        //--------------------------------------------------------------------
+        operator srgba8() const 
+        {
+            srgba8::value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v);
+            return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a));
+        }
+
+		//--------------------------------------------------------------------
+		operator rgba16() const
+		{
+			rgba16::value_type y = uround(v * 65535.0);
+			return rgba16(y, y, y, uround(a * 65535.0));
+		}
+
+		//--------------------------------------------------------------------
+		operator rgba32() const
+		{
+            return rgba32(v, v, v, a);
+		}
+
+		//--------------------------------------------------------------------
+        static AGG_INLINE double to_double(value_type a)
+        {
+            return a;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type from_double(double a)
+        {
+            return value_type(a);
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type empty_value()
+        {
+            return 0;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type full_value()
+        {
+            return 1;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_transparent() const
+        {
+            return a <= 0;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_opaque() const
+        {
+            return a >= 1;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type invert(value_type x) 
+        {
+            return 1 - x;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type multiply(value_type a, value_type b) 
+        {
+            return value_type(a * b);
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type demultiply(value_type a, value_type b) 
+        {
+            return (b == 0) ? 0 : value_type(a / b);
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downscale(T a) 
+        {
+            return a;
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downshift(T a, unsigned n) 
+        {
+            return n > 0 ? a / (1 << n) : a;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type mult_cover(value_type a, cover_type b) 
+        {
+            return value_type(a * b / cover_mask);
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) 
+        {
+            return cover_type(uround(a * b));
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a, assuming q is premultiplied by a.
+        static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) 
+        {
+            return (1 - a) * p + q; // more accurate than "p + q - p * a"
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a.
+        static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) 
+        {
+			// The form "p + a * (q - p)" avoids a multiplication, but may produce an 
+			// inaccurate result. For example, "p + (q - p)" may not be exactly equal 
+			// to q. Therefore, stick to the basic expression, which at least produces 
+			// the correct result at either extreme.
+			return (1 - a) * p + a * q;
+        }
+        
+        //--------------------------------------------------------------------
+        self_type& clear()
+        {
+            v = a = 0;
+			return *this;
+        }
+
+        //--------------------------------------------------------------------
+        self_type& transparent()
+        {
+            a = 0;
+            return *this;
+        }
+
+        //--------------------------------------------------------------------
+        self_type& opacity(double a_)
+        {
+            if (a_ < 0) a = 0;
+            else if (a_ > 1) a = 1;
+            else a = value_type(a_);
+			return *this;
+        }
+
+        //--------------------------------------------------------------------
+        double opacity() const
+        {
+            return a;
+        }
 
 
+        //--------------------------------------------------------------------
+        self_type& premultiply()
+        {
+            if (a < 0) v = 0;
+            else if(a < 1) v *= a;
+            return *this;
+        }
+
+        //--------------------------------------------------------------------
+        self_type& demultiply()
+        {
+            if (a < 0) v = 0;
+            else if (a < 1) v /= a;
+            return *this;
+        }
+
+        //--------------------------------------------------------------------
+        self_type gradient(self_type c, double k) const
+        {
+            return self_type(
+                value_type(v + (c.v - v) * k), 
+                value_type(a + (c.a - a) * k));
+        }
+
+        //--------------------------------------------------------------------
+        static self_type no_color() { return self_type(0,0); }
+    };
 }
 
 
diff --git a/src/agg/agg_color_rgba.h b/src/agg/agg_color_rgba.h
index 77efac8ee..ff33a1179 100644
--- a/src/agg/agg_color_rgba.h
+++ b/src/agg/agg_color_rgba.h
@@ -1,25 +1,12 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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.
+//
 //----------------------------------------------------------------------------
 //
 // Adaptation for high precision colors has been sponsored by 
@@ -39,17 +26,22 @@
 
 #include <math.h>
 #include "agg_basics.h"
+#include "agg_gamma_lut.h"
 
 namespace agg
 {
-    // Supported byte orders for RGB and RGBA pixel formats
+    // Supported component orders for RGB and RGBA pixel formats
     //=======================================================================
-    struct order_rgb  { enum rgb_e  { R=0, G=1, B=2, rgb_tag }; };       //----order_rgb
-    struct order_bgr  { enum bgr_e  { B=0, G=1, R=2, rgb_tag }; };       //----order_bgr
-    struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, rgba_tag }; }; //----order_rgba
-    struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, rgba_tag }; }; //----order_argb
-    struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, rgba_tag }; }; //----order_abgr
-    struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, rgba_tag }; }; //----order_bgra
+    struct order_rgb  { enum rgb_e  { R=0, G=1, B=2, N=3 }; };
+    struct order_bgr  { enum bgr_e  { B=0, G=1, R=2, N=3 }; };
+    struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, N=4 }; };
+    struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, N=4 }; };
+    struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, N=4 }; };
+    struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, N=4 }; };
+
+    // Colorspace tag types.
+    struct linear {};
+    struct sRGB {};
 
     //====================================================================rgba
     struct rgba
@@ -72,24 +64,25 @@ namespace agg
         rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {}
 
         //--------------------------------------------------------------------
-        void clear()
+        rgba& clear()
         {
             r = g = b = a = 0;
+			return *this;
         }
 
         //--------------------------------------------------------------------
-        const rgba& transparent()
+        rgba& transparent()
         {
-            a = 0.0;
+            a = 0;
             return *this;
         }
 
         //--------------------------------------------------------------------
-        const rgba& opacity(double a_)
+        rgba& opacity(double a_)
         {
-            if(a_ < 0.0) a_ = 0.0;
-            if(a_ > 1.0) a_ = 1.0;
-            a = a_;
+            if (a_ < 0) a = 0;
+            else if (a_ > 1) a = 1;
+            else a = a_;
             return *this;
         }
 
@@ -100,7 +93,7 @@ namespace agg
         }
 
         //--------------------------------------------------------------------
-        const rgba& premultiply()
+        rgba& premultiply()
         {
             r *= a;
             g *= a;
@@ -109,33 +102,37 @@ namespace agg
         }
 
         //--------------------------------------------------------------------
-        const rgba& premultiply(double a_)
+        rgba& premultiply(double a_)
         {
-            if(a <= 0.0 || a_ <= 0.0)
+            if (a <= 0 || a_ <= 0)
             {
-                r = g = b = a = 0.0;
-                return *this;
+                r = g = b = a = 0;
+            }
+            else
+            {
+                a_ /= a;
+                r *= a_;
+                g *= a_;
+                b *= a_;
+                a  = a_;
             }
-            a_ /= a;
-            r *= a_;
-            g *= a_;
-            b *= a_;
-            a  = a_;
             return *this;
         }
 
         //--------------------------------------------------------------------
-        const rgba& demultiply()
+        rgba& demultiply()
         {
-            if(a == 0)
+            if (a == 0)
             {
                 r = g = b = 0;
-                return *this;
             }
-            double a_ = 1.0 / a;
-            r *= a_;
-            g *= a_;
-            b *= a_;
+            else
+            {
+                double a_ = 1.0 / a;
+                r *= a_;
+                g *= a_;
+                b *= a_;
+            }
             return *this;
         }
 
@@ -151,12 +148,30 @@ namespace agg
             return ret;
         }
 
+        rgba& operator+=(const rgba& c)
+        {
+            r += c.r;
+            g += c.g;
+            b += c.b;
+            a += c.a;
+            return *this;
+        }
+
+        rgba& operator*=(double k)
+        {
+            r *= k;
+            g *= k;
+            b *= k;
+            a *= k;
+            return *this;
+        }
+
         //--------------------------------------------------------------------
         static rgba no_color() { return rgba(0,0,0,0); }
 
         //--------------------------------------------------------------------
         static rgba from_wavelength(double wl, double gamma = 1.0);
-	
+    
         //--------------------------------------------------------------------
         explicit rgba(double wavelen, double gamma=1.0)
         {
@@ -165,18 +180,14 @@ namespace agg
 
     };
 
-    //----------------------------------------------------------------rgba_pre
-    inline rgba rgba_pre(double r, double g, double b, double a=1.0)
+    inline rgba operator+(const rgba& a, const rgba& b)
     {
-        return rgba(r, g, b, a).premultiply();
+        return rgba(a) += b;
     }
-    inline rgba rgba_pre(const rgba& c)
+
+    inline rgba operator*(const rgba& a, double b)
     {
-        return rgba(c).premultiply();
-    }
-    inline rgba rgba_pre(const rgba& c, double a)
-    {
-        return rgba(c, a).premultiply();
+        return rgba(a) *= b;
     }
 
     //------------------------------------------------------------------------
@@ -184,44 +195,39 @@ namespace agg
     {
         rgba t(0.0, 0.0, 0.0);
 
-        if(wl >= 380.0 && wl <= 440.0)
+        if (wl >= 380.0 && wl <= 440.0)
         {
             t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0);
             t.b = 1.0;
         }
-        else 
-        if(wl >= 440.0 && wl <= 490.0)
+        else if (wl >= 440.0 && wl <= 490.0)
         {
             t.g = (wl - 440.0) / (490.0 - 440.0);
             t.b = 1.0;
         }
-        else
-        if(wl >= 490.0 && wl <= 510.0)
+        else if (wl >= 490.0 && wl <= 510.0)
         {
             t.g = 1.0;
             t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0);
         }
-        else
-        if(wl >= 510.0 && wl <= 580.0)
+        else if (wl >= 510.0 && wl <= 580.0)
         {
             t.r = (wl - 510.0) / (580.0 - 510.0);
             t.g = 1.0;
         }
-        else
-        if(wl >= 580.0 && wl <= 645.0)
+        else if (wl >= 580.0 && wl <= 645.0)
         {
             t.r = 1.0;
             t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0);
         }
-        else
-        if(wl >= 645.0 && wl <= 780.0)
+        else if (wl >= 645.0 && wl <= 780.0)
         {
             t.r = 1.0;
         }
 
         double s = 1.0;
-        if(wl > 700.0)       s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0);
-        else if(wl <  420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0);
+        if (wl > 700.0)       s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0);
+        else if (wl <  420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0);
 
         t.r = pow(t.r * s, gamma);
         t.g = pow(t.g * s, gamma);
@@ -229,11 +235,15 @@ namespace agg
         return t;
     }
 
-
+    inline rgba rgba_pre(double r, double g, double b, double a)
+    {
+        return rgba(r, g, b, a).premultiply();
+    }
 
     
     //===================================================================rgba8
-    struct rgba8
+    template<class Colorspace>
+    struct rgba8T
     {
         typedef int8u  value_type;
         typedef int32u calc_type;
@@ -242,9 +252,10 @@ namespace agg
         {
             base_shift = 8,
             base_scale = 1 << base_shift,
-            base_mask  = base_scale - 1
+            base_mask  = base_scale - 1,
+            base_MSB = 1 << (base_shift - 1)
         };
-        typedef rgba8 self_type;
+        typedef rgba8T self_type;
 
 
         value_type r;
@@ -252,53 +263,218 @@ namespace agg
         value_type b;
         value_type a;
 
-        //--------------------------------------------------------------------
-        rgba8() {}
+        static void convert(rgba8T<linear>& dst, const rgba8T<sRGB>& src)
+        {
+            dst.r = sRGB_conv<value_type>::rgb_from_sRGB(src.r);
+            dst.g = sRGB_conv<value_type>::rgb_from_sRGB(src.g);
+            dst.b = sRGB_conv<value_type>::rgb_from_sRGB(src.b);
+            dst.a = src.a;
+        }
+
+        static void convert(rgba8T<sRGB>& dst, const rgba8T<linear>& src)
+        {
+            dst.r = sRGB_conv<value_type>::rgb_to_sRGB(src.r);
+            dst.g = sRGB_conv<value_type>::rgb_to_sRGB(src.g);
+            dst.b = sRGB_conv<value_type>::rgb_to_sRGB(src.b);
+            dst.a = src.a;
+        }
+
+        static void convert(rgba8T<linear>& dst, const rgba& src)
+        {
+            dst.r = value_type(uround(src.r * base_mask));
+            dst.g = value_type(uround(src.g * base_mask));
+            dst.b = value_type(uround(src.b * base_mask));
+            dst.a = value_type(uround(src.a * base_mask));
+        }
+
+        static void convert(rgba8T<sRGB>& dst, const rgba& src)
+        {
+            // Use the "float" table.
+            dst.r = sRGB_conv<float>::rgb_to_sRGB(float(src.r));
+            dst.g = sRGB_conv<float>::rgb_to_sRGB(float(src.g));
+            dst.b = sRGB_conv<float>::rgb_to_sRGB(float(src.b));
+            dst.a = sRGB_conv<float>::alpha_to_sRGB(float(src.a));
+        }
+
+        static void convert(rgba& dst, const rgba8T<linear>& src)
+        {
+            dst.r = src.r / 255.0;
+            dst.g = src.g / 255.0;
+            dst.b = src.b / 255.0;
+            dst.a = src.a / 255.0;
+        }
+
+        static void convert(rgba& dst, const rgba8T<sRGB>& src)
+        {
+            // Use the "float" table.
+            dst.r = sRGB_conv<float>::rgb_from_sRGB(src.r);
+            dst.g = sRGB_conv<float>::rgb_from_sRGB(src.g);
+            dst.b = sRGB_conv<float>::rgb_from_sRGB(src.b);
+            dst.a = sRGB_conv<float>::alpha_from_sRGB(src.a);
+        }
 
         //--------------------------------------------------------------------
-        rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
+        rgba8T() {}
+
+        //--------------------------------------------------------------------
+        rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask) :
             r(value_type(r_)), 
             g(value_type(g_)), 
             b(value_type(b_)), 
             a(value_type(a_)) {}
 
         //--------------------------------------------------------------------
-        rgba8(const rgba& c, double a_) :
-            r((value_type)uround(c.r * double(base_mask))), 
-            g((value_type)uround(c.g * double(base_mask))), 
-            b((value_type)uround(c.b * double(base_mask))), 
-            a((value_type)uround(a_  * double(base_mask))) {}
+        rgba8T(const rgba& c)
+        {
+            convert(*this, c);
+        }
 
         //--------------------------------------------------------------------
-        rgba8(const self_type& c, unsigned a_) :
+        rgba8T(const self_type& c, unsigned a_) :
             r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
 
         //--------------------------------------------------------------------
-        rgba8(const rgba& c) :
-            r((value_type)uround(c.r * double(base_mask))), 
-            g((value_type)uround(c.g * double(base_mask))), 
-            b((value_type)uround(c.b * double(base_mask))), 
-            a((value_type)uround(c.a * double(base_mask))) {}
+        template<class T>
+        rgba8T(const rgba8T<T>& c)
+        {
+            convert(*this, c);
+        }
 
         //--------------------------------------------------------------------
-        void clear()
+        operator rgba() const 
         {
-            r = g = b = a = 0;
+            rgba c;
+            convert(c, *this);
+            return c;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE double to_double(value_type a)
+        {
+            return double(a) / base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type from_double(double a)
+        {
+            return value_type(uround(a * base_mask));
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type empty_value()
+        {
+            return 0;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type full_value()
+        {
+            return base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_transparent() const
+        {
+            return a == 0;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_opaque() const
+        {
+            return a == base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type invert(value_type x) 
+        {
+            return base_mask - x;
+        }
+
+        //--------------------------------------------------------------------
+        // Fixed-point multiply, exact over int8u.
+        static AGG_INLINE value_type multiply(value_type a, value_type b) 
+        {
+            calc_type t = a * b + base_MSB;
+            return value_type(((t >> base_shift) + t) >> base_shift);
         }
         
         //--------------------------------------------------------------------
-        const self_type& transparent()
+        static AGG_INLINE value_type demultiply(value_type a, value_type b) 
+        {
+            if (a * b == 0)
+            {
+                return 0;
+            }
+            else if (a >= b)
+            {
+                return base_mask;
+            }
+            else return value_type((a * base_mask + (b >> 1)) / b); 
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downscale(T a) 
+        {
+            return a >> base_shift;
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downshift(T a, unsigned n) 
+        {
+            return a >> n;
+        }
+
+        //--------------------------------------------------------------------
+        // Fixed-point multiply, exact over int8u.
+        // Specifically for multiplying a color component by a cover.
+        static AGG_INLINE value_type mult_cover(value_type a, cover_type b) 
+        {
+            return multiply(a, b);
+        }
+        
+        //--------------------------------------------------------------------
+        static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) 
+        {
+            return multiply(b, a);
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a, assuming q is premultiplied by a.
+        static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) 
+        {
+            return p + q - multiply(p, a);
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a.
+        static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) 
+        {
+            int t = (q - p) * a + base_MSB - (p > q);
+            return value_type(p + (((t >> base_shift) + t) >> base_shift));
+        }
+        
+        //--------------------------------------------------------------------
+        self_type& clear()
+        {
+            r = g = b = a = 0;
+			return *this;
+        }
+        
+        //--------------------------------------------------------------------
+        self_type& transparent()
         {
             a = 0;
             return *this;
         }
 
         //--------------------------------------------------------------------
-        const self_type& opacity(double a_)
+        self_type& opacity(double a_)
         {
-            if(a_ < 0.0) a_ = 0.0;
-            if(a_ > 1.0) a_ = 1.0;
-            a = (value_type)uround(a_ * double(base_mask));
+            if (a_ < 0) a = 0;
+            else if (a_ > 1) a = 1;
+            else a = (value_type)uround(a_ * double(base_mask));
             return *this;
         }
 
@@ -309,54 +485,66 @@ namespace agg
         }
 
         //--------------------------------------------------------------------
-        AGG_INLINE const self_type& premultiply()
+        AGG_INLINE self_type& premultiply()
         {
-            if(a == base_mask) return *this;
-            if(a == 0)
+            if (a != base_mask)
             {
-                r = g = b = 0;
-                return *this;
+                if (a == 0)
+                {
+                    r = g = b = 0;
+                }
+                else
+                {
+                    r = multiply(r, a);
+                    g = multiply(g, a);
+                    b = multiply(b, a);
+                }
             }
-            r = value_type((calc_type(r) * a) >> base_shift);
-            g = value_type((calc_type(g) * a) >> base_shift);
-            b = value_type((calc_type(b) * a) >> base_shift);
             return *this;
         }
 
         //--------------------------------------------------------------------
-        AGG_INLINE const self_type& premultiply(unsigned a_)
+        AGG_INLINE self_type& premultiply(unsigned a_)
         {
-            if(a == base_mask && a_ >= base_mask) return *this;
-            if(a == 0 || a_ == 0)
+            if (a != base_mask || a_ < base_mask)
             {
-                r = g = b = a = 0;
-                return *this;
+                if (a == 0 || a_ == 0)
+                {
+                    r = g = b = a = 0;
+                }
+                else
+                {
+                    calc_type r_ = (calc_type(r) * a_) / a;
+                    calc_type g_ = (calc_type(g) * a_) / a;
+                    calc_type b_ = (calc_type(b) * a_) / a;
+                    r = value_type((r_ > a_) ? a_ : r_);
+                    g = value_type((g_ > a_) ? a_ : g_);
+                    b = value_type((b_ > a_) ? a_ : b_);
+                    a = value_type(a_);
+                }
             }
-            calc_type r_ = (calc_type(r) * a_) / a;
-            calc_type g_ = (calc_type(g) * a_) / a;
-            calc_type b_ = (calc_type(b) * a_) / a;
-            r = value_type((r_ > a_) ? a_ : r_);
-            g = value_type((g_ > a_) ? a_ : g_);
-            b = value_type((b_ > a_) ? a_ : b_);
-            a = value_type(a_);
             return *this;
         }
 
         //--------------------------------------------------------------------
-        AGG_INLINE const self_type& demultiply()
+        AGG_INLINE self_type& demultiply()
         {
-            if(a == base_mask) return *this;
-            if(a == 0)
+            if (a < base_mask)
             {
-                r = g = b = 0;
-                return *this;
+                if (a == 0)
+                {
+                    r = g = b = 0;
+                }
+                else
+                {
+                    calc_type r_ = (calc_type(r) * base_mask) / a;
+                    calc_type g_ = (calc_type(g) * base_mask) / a;
+                    calc_type b_ = (calc_type(b) * base_mask) / a;
+                    r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
+                    g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
+                    b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
+                }
             }
-            calc_type r_ = (calc_type(r) * base_mask) / a;
-            calc_type g_ = (calc_type(g) * base_mask) / a;
-            calc_type b_ = (calc_type(b) * base_mask) / a;
-            r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
-            g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
-            b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
             return *this;
         }
 
@@ -364,11 +552,11 @@ namespace agg
         AGG_INLINE self_type gradient(const self_type& c, double k) const
         {
             self_type ret;
-            calc_type ik = uround(k * base_scale);
-            ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
-            ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
-            ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
-            ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
+            calc_type ik = uround(k * base_mask);
+            ret.r = lerp(r, c.r, ik);
+            ret.g = lerp(g, c.g, ik);
+            ret.b = lerp(b, c.b, ik);
+            ret.a = lerp(a, c.a, ik);
             return ret;
         }
 
@@ -376,31 +564,32 @@ namespace agg
         AGG_INLINE void add(const self_type& c, unsigned cover)
         {
             calc_type cr, cg, cb, ca;
-            if(cover == cover_mask)
+            if (cover == cover_mask)
             {
-                if(c.a == base_mask) 
+                if (c.a == base_mask) 
                 {
                     *this = c;
+                    return;
                 }
                 else
                 {
-                    cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
-                    cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
-                    cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
-                    ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+                    cr = r + c.r; 
+                    cg = g + c.g; 
+                    cb = b + c.b; 
+                    ca = a + c.a; 
                 }
             }
             else
             {
-                cr = r + ((c.r * cover + cover_mask/2) >> cover_shift);
-                cg = g + ((c.g * cover + cover_mask/2) >> cover_shift);
-                cb = b + ((c.b * cover + cover_mask/2) >> cover_shift);
-                ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
-                r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
-                g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
-                b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
-                a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+                cr = r + mult_cover(c.r, cover);
+                cg = g + mult_cover(c.g, cover);
+                cb = b + mult_cover(c.b, cover);
+                ca = a + mult_cover(c.a, cover);
             }
+            r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr);
+            g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg);
+            b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb);
+            a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
         }
 
         //--------------------------------------------------------------------
@@ -431,29 +620,8 @@ namespace agg
         }
     };
 
-
-    //-------------------------------------------------------------rgba8_pre
-    inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, 
-                           unsigned a = rgba8::base_mask)
-    {
-        return rgba8(r,g,b,a).premultiply();
-    }
-    inline rgba8 rgba8_pre(const rgba8& c)
-    {
-        return rgba8(c).premultiply();
-    }
-    inline rgba8 rgba8_pre(const rgba8& c, unsigned a)
-    {
-        return rgba8(c,a).premultiply();
-    }
-    inline rgba8 rgba8_pre(const rgba& c)
-    {
-        return rgba8(c).premultiply();
-    }
-    inline rgba8 rgba8_pre(const rgba& c, double a)
-    {
-        return rgba8(c,a).premultiply();
-    }
+    typedef rgba8T<linear> rgba8;
+    typedef rgba8T<sRGB> srgba8;
 
 
     //-------------------------------------------------------------rgb8_packed
@@ -490,8 +658,6 @@ namespace agg
 
 
 
-
-
     //==================================================================rgba16
     struct rgba16
     {
@@ -502,7 +668,8 @@ namespace agg
         {
             base_shift = 16,
             base_scale = 1 << base_shift,
-            base_mask  = base_scale - 1
+            base_mask  = base_scale - 1,
+            base_MSB = 1 << (base_shift - 1)
         };
         typedef rgba16 self_type;
 
@@ -532,13 +699,6 @@ namespace agg
             b((value_type)uround(c.b * double(base_mask))), 
             a((value_type)uround(c.a * double(base_mask))) {}
 
-        //--------------------------------------------------------------------
-        rgba16(const rgba& c, double a_) :
-            r((value_type)uround(c.r * double(base_mask))), 
-            g((value_type)uround(c.g * double(base_mask))), 
-            b((value_type)uround(c.b * double(base_mask))), 
-            a((value_type)uround(a_  * double(base_mask))) {}
-
         //--------------------------------------------------------------------
         rgba16(const rgba8& c) :
             r(value_type((value_type(c.r) << 8) | c.r)), 
@@ -547,31 +707,166 @@ namespace agg
             a(value_type((value_type(c.a) << 8) | c.a)) {}
 
         //--------------------------------------------------------------------
-        rgba16(const rgba8& c, unsigned a_) :
-            r(value_type((value_type(c.r) << 8) | c.r)), 
-            g(value_type((value_type(c.g) << 8) | c.g)), 
-            b(value_type((value_type(c.b) << 8) | c.b)), 
-            a(value_type((             a_ << 8) | c.a)) {}
+        rgba16(const srgba8& c) :
+            r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)), 
+            g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)), 
+            b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)), 
+            a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
 
         //--------------------------------------------------------------------
-        void clear()
+        operator rgba() const 
         {
-            r = g = b = a = 0;
+            return rgba(
+                r / 65535.0, 
+                g / 65535.0, 
+                b / 65535.0, 
+                a / 65535.0);
+        }
+
+        //--------------------------------------------------------------------
+        operator rgba8() const 
+        {
+            return rgba8(r >> 8, g >> 8, b >> 8, a >> 8);
+        }
+
+        //--------------------------------------------------------------------
+        operator srgba8() const 
+        {
+            // Return (non-premultiplied) sRGB values.
+            return srgba8(
+                sRGB_conv<value_type>::rgb_to_sRGB(r), 
+                sRGB_conv<value_type>::rgb_to_sRGB(g), 
+                sRGB_conv<value_type>::rgb_to_sRGB(b), 
+                sRGB_conv<value_type>::alpha_to_sRGB(a));
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE double to_double(value_type a)
+        {
+            return double(a) / base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type from_double(double a)
+        {
+            return value_type(uround(a * base_mask));
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type empty_value()
+        {
+            return 0;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type full_value()
+        {
+            return base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_transparent() const
+        {
+            return a == 0;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_opaque() const
+        {
+            return a == base_mask;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type invert(value_type x) 
+        {
+            return base_mask - x;
+        }
+
+        //--------------------------------------------------------------------
+        // Fixed-point multiply, exact over int16u.
+        static AGG_INLINE value_type multiply(value_type a, value_type b) 
+        {
+            calc_type t = a * b + base_MSB;
+            return value_type(((t >> base_shift) + t) >> base_shift);
         }
         
         //--------------------------------------------------------------------
-        const self_type& transparent()
+        static AGG_INLINE value_type demultiply(value_type a, value_type b) 
+        {
+            if (a * b == 0)
+            {
+                return 0;
+            }
+            else if (a >= b)
+            {
+                return base_mask;
+            }
+            else return value_type((a * base_mask + (b >> 1)) / b); 
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downscale(T a) 
+        {
+            return a >> base_shift;
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downshift(T a, unsigned n) 
+        {
+            return a >> n;
+        }
+
+        //--------------------------------------------------------------------
+        // Fixed-point multiply, almost exact over int16u.
+        // Specifically for multiplying a color component by a cover.
+        static AGG_INLINE value_type mult_cover(value_type a, cover_type b) 
+        {
+            return multiply(a, (b << 8) | b);
+        }
+        
+        //--------------------------------------------------------------------
+        static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) 
+        {
+            return multiply((a << 8) | a, b) >> 8;
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a, assuming q is premultiplied by a.
+        static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) 
+        {
+            return p + q - multiply(p, a);
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a.
+        static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) 
+        {
+            int t = (q - p) * a + base_MSB - (p > q);
+            return value_type(p + (((t >> base_shift) + t) >> base_shift));
+        }
+        
+        //--------------------------------------------------------------------
+        self_type& clear()
+        {
+            r = g = b = a = 0;
+			return *this;
+        }
+        
+        //--------------------------------------------------------------------
+        self_type& transparent()
         {
             a = 0;
             return *this;
         }
 
         //--------------------------------------------------------------------
-        AGG_INLINE const self_type& opacity(double a_)
+        AGG_INLINE self_type& opacity(double a_)
         {
-            if(a_ < 0.0) a_ = 0.0;
-            if(a_ > 1.0) a_ = 1.0;
-            a = (value_type)uround(a_ * double(base_mask));
+            if (a_ < 0) a = 0;
+            if (a_ > 1) a = 1;
+            a = value_type(uround(a_ * double(base_mask)));
             return *this;
         }
 
@@ -582,54 +877,66 @@ namespace agg
         }
 
         //--------------------------------------------------------------------
-        AGG_INLINE const self_type& premultiply()
+        AGG_INLINE self_type& premultiply()
         {
-            if(a == base_mask) return *this;
-            if(a == 0)
+            if (a != base_mask) 
             {
-                r = g = b = 0;
-                return *this;
+                if (a == 0)
+                {
+                    r = g = b = 0;
+                }
+                else
+                {
+                    r = multiply(r, a);
+                    g = multiply(g, a);
+                    b = multiply(b, a);
+                }
             }
-            r = value_type((calc_type(r) * a) >> base_shift);
-            g = value_type((calc_type(g) * a) >> base_shift);
-            b = value_type((calc_type(b) * a) >> base_shift);
             return *this;
         }
 
         //--------------------------------------------------------------------
-        AGG_INLINE const self_type& premultiply(unsigned a_)
+        AGG_INLINE self_type& premultiply(unsigned a_)
         {
-            if(a == base_mask && a_ >= base_mask) return *this;
-            if(a == 0 || a_ == 0)
+            if (a < base_mask || a_ < base_mask)
             {
-                r = g = b = a = 0;
-                return *this;
+                if (a == 0 || a_ == 0)
+                {
+                    r = g = b = a = 0;
+                }
+                else
+                {
+                    calc_type r_ = (calc_type(r) * a_) / a;
+                    calc_type g_ = (calc_type(g) * a_) / a;
+                    calc_type b_ = (calc_type(b) * a_) / a;
+                    r = value_type((r_ > a_) ? a_ : r_);
+                    g = value_type((g_ > a_) ? a_ : g_);
+                    b = value_type((b_ > a_) ? a_ : b_);
+                    a = value_type(a_);
+                }
             }
-            calc_type r_ = (calc_type(r) * a_) / a;
-            calc_type g_ = (calc_type(g) * a_) / a;
-            calc_type b_ = (calc_type(b) * a_) / a;
-            r = value_type((r_ > a_) ? a_ : r_);
-            g = value_type((g_ > a_) ? a_ : g_);
-            b = value_type((b_ > a_) ? a_ : b_);
-            a = value_type(a_);
             return *this;
         }
 
         //--------------------------------------------------------------------
-        AGG_INLINE const self_type& demultiply()
+        AGG_INLINE self_type& demultiply()
         {
-            if(a == base_mask) return *this;
-            if(a == 0)
+            if (a < base_mask)
             {
-                r = g = b = 0;
-                return *this;
+                if (a == 0)
+                {
+                    r = g = b = 0;
+                }
+                else
+                {
+                    calc_type r_ = (calc_type(r) * base_mask) / a;
+                    calc_type g_ = (calc_type(g) * base_mask) / a;
+                    calc_type b_ = (calc_type(b) * base_mask) / a;
+                    r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
+                    g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
+                    b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
+                }
             }
-            calc_type r_ = (calc_type(r) * base_mask) / a;
-            calc_type g_ = (calc_type(g) * base_mask) / a;
-            calc_type b_ = (calc_type(b) * base_mask) / a;
-            r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
-            g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
-            b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
             return *this;
         }
 
@@ -637,11 +944,11 @@ namespace agg
         AGG_INLINE self_type gradient(const self_type& c, double k) const
         {
             self_type ret;
-            calc_type ik = uround(k * base_scale);
-            ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
-            ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
-            ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
-            ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
+            calc_type ik = uround(k * base_mask);
+            ret.r = lerp(r, c.r, ik);
+            ret.g = lerp(g, c.g, ik);
+            ret.b = lerp(b, c.b, ik);
+            ret.a = lerp(a, c.a, ik);
             return ret;
         }
 
@@ -649,31 +956,32 @@ namespace agg
         AGG_INLINE void add(const self_type& c, unsigned cover)
         {
             calc_type cr, cg, cb, ca;
-            if(cover == cover_mask)
+            if (cover == cover_mask)
             {
-                if(c.a == base_mask) 
+                if (c.a == base_mask) 
                 {
                     *this = c;
+                    return;
                 }
                 else
                 {
-                    cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
-                    cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
-                    cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
-                    ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+                    cr = r + c.r; 
+                    cg = g + c.g; 
+                    cb = b + c.b; 
+                    ca = a + c.a; 
                 }
             }
             else
             {
-                cr = r + ((c.r * cover + cover_mask) >> cover_shift);
-                cg = g + ((c.g * cover + cover_mask) >> cover_shift);
-                cb = b + ((c.b * cover + cover_mask) >> cover_shift);
-                ca = a + ((c.a * cover + cover_mask) >> cover_shift);
-                r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
-                g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
-                b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
-                a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+                cr = r + mult_cover(c.r, cover);
+                cg = g + mult_cover(c.g, cover);
+                cb = b + mult_cover(c.b, cover);
+                ca = a + mult_cover(c.a, cover);
             }
+            r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr);
+            g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg);
+            b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb);
+            a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
         }
 
         //--------------------------------------------------------------------
@@ -705,35 +1013,6 @@ namespace agg
     };
 
 
-
-    //--------------------------------------------------------------rgba16_pre
-    inline rgba16 rgba16_pre(unsigned r, unsigned g, unsigned b, 
-                             unsigned a = rgba16::base_mask)
-    {
-        return rgba16(r,g,b,a).premultiply();
-    }
-    inline rgba16 rgba16_pre(const rgba16& c, unsigned a)
-    {
-        return rgba16(c,a).premultiply();
-    }
-    inline rgba16 rgba16_pre(const rgba& c)
-    {
-        return rgba16(c).premultiply();
-    }
-    inline rgba16 rgba16_pre(const rgba& c, double a)
-    {
-        return rgba16(c,a).premultiply();
-    }
-    inline rgba16 rgba16_pre(const rgba8& c)
-    {
-        return rgba16(c).premultiply();
-    }
-    inline rgba16 rgba16_pre(const rgba8& c, unsigned a)
-    {
-        return rgba16(c,a).premultiply();
-    }
-
-
     //------------------------------------------------------rgba16_gamma_dir
     template<class GammaLUT>
     rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma)
@@ -748,7 +1027,325 @@ namespace agg
         return rgba16(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a);
     }
 
+    //====================================================================rgba32
+    struct rgba32
+    {
+        typedef float value_type;
+        typedef double calc_type;
+        typedef double long_type;
+        typedef rgba32 self_type;
 
+        value_type r;
+        value_type g;
+        value_type b;
+        value_type a;
+
+        //--------------------------------------------------------------------
+        rgba32() {}
+
+        //--------------------------------------------------------------------
+        rgba32(value_type r_, value_type g_, value_type b_, value_type a_= 1) :
+            r(r_), g(g_), b(b_), a(a_) {}
+
+        //--------------------------------------------------------------------
+        rgba32(const self_type& c, float a_) :
+            r(c.r), g(c.g), b(c.b), a(a_) {}
+
+        //--------------------------------------------------------------------
+        rgba32(const rgba& c) :
+            r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {}
+
+        //--------------------------------------------------------------------
+        rgba32(const rgba8& c) :
+            r(value_type(c.r / 255.0)), 
+            g(value_type(c.g / 255.0)), 
+            b(value_type(c.b / 255.0)), 
+            a(value_type(c.a / 255.0)) {}
+
+        //--------------------------------------------------------------------
+        rgba32(const srgba8& c) :
+            r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)), 
+            g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)), 
+            b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)), 
+            a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
+
+        //--------------------------------------------------------------------
+        rgba32(const rgba16& c) :
+            r(value_type(c.r / 65535.0)), 
+            g(value_type(c.g / 65535.0)), 
+            b(value_type(c.b / 65535.0)), 
+            a(value_type(c.a / 65535.0)) {}
+
+        //--------------------------------------------------------------------
+        operator rgba() const 
+        {
+            return rgba(r, g, b, a);
+        }
+
+        //--------------------------------------------------------------------
+        operator rgba8() const 
+        {
+            return rgba8(
+                uround(r * 255.0), 
+                uround(g * 255.0), 
+                uround(b * 255.0), 
+                uround(a * 255.0));
+        }
+
+        //--------------------------------------------------------------------
+        operator srgba8() const 
+        {
+            return srgba8(
+                sRGB_conv<value_type>::rgb_to_sRGB(r), 
+                sRGB_conv<value_type>::rgb_to_sRGB(g), 
+                sRGB_conv<value_type>::rgb_to_sRGB(b), 
+                sRGB_conv<value_type>::alpha_to_sRGB(a));
+        }
+
+        //--------------------------------------------------------------------
+        operator rgba16() const 
+        {
+            return rgba8(
+                uround(r * 65535.0), 
+                uround(g * 65535.0), 
+                uround(b * 65535.0), 
+                uround(a * 65535.0));
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE double to_double(value_type a)
+        {
+            return a;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type from_double(double a)
+        {
+            return value_type(a);
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type empty_value()
+        {
+            return 0;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type full_value()
+        {
+            return 1;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_transparent() const
+        {
+            return a <= 0;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE bool is_opaque() const
+        {
+            return a >= 1;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type invert(value_type x) 
+        {
+            return 1 - x;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type multiply(value_type a, value_type b) 
+        {
+            return value_type(a * b);
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type demultiply(value_type a, value_type b) 
+        {
+            return (b == 0) ? 0 : value_type(a / b);
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downscale(T a) 
+        {
+            return a;
+        }
+
+        //--------------------------------------------------------------------
+        template<typename T>
+        static AGG_INLINE T downshift(T a, unsigned n) 
+        {
+            return n > 0 ? a / (1 << n) : a;
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE value_type mult_cover(value_type a, cover_type b) 
+        {
+            return value_type(a * b / cover_mask);
+        }
+
+        //--------------------------------------------------------------------
+        static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) 
+        {
+            return cover_type(uround(a * b));
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a, assuming q is premultiplied by a.
+        static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) 
+        {
+            return (1 - a) * p + q; // more accurate than "p + q - p * a"
+        }
+        
+        //--------------------------------------------------------------------
+        // Interpolate p to q by a.
+        static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) 
+        {
+			// The form "p + a * (q - p)" avoids a multiplication, but may produce an 
+			// inaccurate result. For example, "p + (q - p)" may not be exactly equal 
+			// to q. Therefore, stick to the basic expression, which at least produces 
+			// the correct result at either extreme.
+			return (1 - a) * p + a * q;
+        }
+        
+        //--------------------------------------------------------------------
+        self_type& clear()
+        {
+            r = g = b = a = 0;
+			return *this;
+        }
+        
+        //--------------------------------------------------------------------
+        self_type& transparent()
+        {
+            a = 0;
+            return *this;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE self_type& opacity(double a_)
+        {
+            if (a_ < 0) a = 0;
+            else if (a_ > 1) a = 1;
+            else a = value_type(a_);
+            return *this;
+        }
+
+        //--------------------------------------------------------------------
+        double opacity() const
+        {
+            return a;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE self_type& premultiply()
+        {
+            if (a < 1)
+            {
+                if (a <= 0)
+                {
+                    r = g = b = 0;
+                }
+                else
+                {
+                    r *= a;
+                    g *= a;
+                    b *= a;
+                }
+            }
+            return *this;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE self_type& demultiply()
+        {
+            if (a < 1)
+            {
+                if (a <= 0)
+                {
+                    r = g = b = 0;
+                }
+                else
+                {
+                    r /= a;
+                    g /= a;
+                    b /= a;
+                }
+            }
+            return *this;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE self_type gradient(const self_type& c, double k) const
+        {
+            self_type ret;
+            ret.r = value_type(r + (c.r - r) * k);
+            ret.g = value_type(g + (c.g - g) * k);
+            ret.b = value_type(b + (c.b - b) * k);
+            ret.a = value_type(a + (c.a - a) * k);
+            return ret;
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE void add(const self_type& c, unsigned cover)
+        {
+            if (cover == cover_mask)
+            {
+                if (c.is_opaque()) 
+                {
+                    *this = c;
+                    return;
+                }
+                else
+                {
+                    r += c.r; 
+                    g += c.g; 
+                    b += c.b; 
+                    a += c.a; 
+                }
+            }
+            else
+            {
+                r += mult_cover(c.r, cover);
+                g += mult_cover(c.g, cover);
+                b += mult_cover(c.b, cover);
+                a += mult_cover(c.a, cover);
+            }
+            if (a > 1) a = 1;
+            if (r > a) r = a;
+            if (g > a) g = a;
+            if (b > a) b = a;
+        }
+
+        //--------------------------------------------------------------------
+        template<class GammaLUT>
+        AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
+        {
+            r = gamma.dir(r);
+            g = gamma.dir(g);
+            b = gamma.dir(b);
+        }
+
+        //--------------------------------------------------------------------
+        template<class GammaLUT>
+        AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
+        {
+            r = gamma.inv(r);
+            g = gamma.inv(g);
+            b = gamma.inv(b);
+        }
+
+        //--------------------------------------------------------------------
+        static self_type no_color() { return self_type(0,0,0,0); }
+
+        //--------------------------------------------------------------------
+        static self_type from_wavelength(double wl, double gamma = 1)
+        {
+            return self_type(rgba::from_wavelength(wl, gamma));
+        }
+    };
 }
 
 
diff --git a/src/agg/agg_config.h b/src/agg/agg_config.h
index 81c75f124..fa1dae2ba 100644
--- a/src/agg/agg_config.h
+++ b/src/agg/agg_config.h
@@ -37,7 +37,7 @@
 // Provides cheaper creation and destruction (no mem allocs):
 // #define AGG_RENDERING_BUFFER row_accessor<int8u>
 //
-// You can still use both of them simultaneouslyin your applications 
+// You can still use both of them simultaneously in your applications 
 // This #define is used only for default rendering_buffer type,
 // in short hand typedefs like pixfmt_rgba32.
 
diff --git a/src/agg/agg_conv_adaptor_vcgen.h b/src/agg/agg_conv_adaptor_vcgen.h
deleted file mode 100644
index 7bd9b0709..000000000
--- a/src/agg/agg_conv_adaptor_vcgen.h
+++ /dev/null
@@ -1,166 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED
-#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED
-
-#include "agg_basics.h"
-
-namespace agg
-{
-    //------------------------------------------------------------null_markers
-    struct null_markers
-    {
-        void remove_all() {}
-        void add_vertex(double, double, unsigned) {}
-        void prepare_src() {}
-
-        void rewind(unsigned) {}
-        unsigned vertex(double*, double*) { return path_cmd_stop; }
-    };
-
-
-    //------------------------------------------------------conv_adaptor_vcgen
-    template<class VertexSource, 
-             class Generator, 
-             class Markers=null_markers> class conv_adaptor_vcgen
-    {
-        enum status
-        {
-            initial,
-            accumulate,
-            generate
-        };
-
-    public:
-        explicit conv_adaptor_vcgen(VertexSource& source) :
-            m_source(&source), 
-            m_status(initial)
-        {}
-        void attach(VertexSource& source) { m_source = &source; }
-
-        Generator& generator() { return m_generator; }
-        const Generator& generator() const { return m_generator; }
-
-        Markers& markers() { return m_markers; }
-        const Markers& markers() const { return m_markers; }
-        
-        void rewind(unsigned path_id) 
-        { 
-            m_source->rewind(path_id); 
-            m_status = initial;
-        }
-
-        unsigned vertex(double* x, double* y);
-
-    private:
-        // Prohibit copying
-        conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
-        const conv_adaptor_vcgen<VertexSource, Generator, Markers>& 
-            operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
-
-        VertexSource* m_source;
-        Generator     m_generator;
-        Markers       m_markers;
-        status        m_status;
-        unsigned      m_last_cmd;
-        double        m_start_x;
-        double        m_start_y;
-    };
-
-
-
-
-
-    //------------------------------------------------------------------------
-    template<class VertexSource, class Generator, class Markers> 
-    unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x, double* y)
-    {
-        unsigned cmd = path_cmd_stop;
-        bool done = false;
-        while(!done)
-        {
-            switch(m_status)
-            {
-            case initial:
-                m_markers.remove_all();
-                m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
-                m_status = accumulate;
-
-            case accumulate:
-                if(is_stop(m_last_cmd)) return path_cmd_stop;
-
-                m_generator.remove_all();
-                m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
-                m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
-
-                for(;;)
-                {
-                    cmd = m_source->vertex(x, y);
-                    if(is_vertex(cmd))
-                    {
-                        m_last_cmd = cmd;
-                        if(is_move_to(cmd))
-                        {
-                            m_start_x = *x;
-                            m_start_y = *y;
-                            break;
-                        }
-                        m_generator.add_vertex(*x, *y, cmd);
-                        m_markers.add_vertex(*x, *y, path_cmd_line_to);
-                    }
-                    else
-                    {
-                        if(is_stop(cmd))
-                        {
-                            m_last_cmd = path_cmd_stop;
-                            break;
-                        }
-                        if(is_end_poly(cmd))
-                        {
-                            m_generator.add_vertex(*x, *y, cmd);
-                            break;
-                        }
-                    }
-                }
-                m_generator.rewind(0);
-                m_status = generate;
-
-            case generate:
-                cmd = m_generator.vertex(x, y);
-                if(is_stop(cmd))
-                {
-                    m_status = accumulate;
-                    break;
-                }
-                done = true;
-                break;
-            }
-        }
-        return cmd;
-    }
-
-}
-
-#endif
diff --git a/src/agg/agg_conv_contour.h b/src/agg/agg_conv_contour.h
deleted file mode 100644
index dd29861b4..000000000
--- a/src/agg/agg_conv_contour.h
+++ /dev/null
@@ -1,71 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_CONV_CONTOUR_INCLUDED
-#define AGG_CONV_CONTOUR_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_vcgen_contour.h"
-#include "agg_conv_adaptor_vcgen.h"
-
-namespace agg
-{
-
-    //-----------------------------------------------------------conv_contour
-    template<class VertexSource> 
-    struct conv_contour : public conv_adaptor_vcgen<VertexSource, vcgen_contour>
-    {
-        typedef conv_adaptor_vcgen<VertexSource, vcgen_contour> base_type;
-
-        conv_contour(VertexSource& vs) : 
-            conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs)
-        {
-        }
-
-        void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
-        void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
-        void width(double w) { base_type::generator().width(w); }
-        void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
-        void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
-        void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
-        void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
-        void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); }
-
-        line_join_e line_join() const { return base_type::generator().line_join(); }
-        inner_join_e inner_join() const { return base_type::generator().inner_join(); }
-        double width() const { return base_type::generator().width(); }
-        double miter_limit() const { return base_type::generator().miter_limit(); }
-        double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
-        double approximation_scale() const { return base_type::generator().approximation_scale(); }
-        bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); }
-
-    private:
-        conv_contour(const conv_contour<VertexSource>&);
-        const conv_contour<VertexSource>& 
-            operator = (const conv_contour<VertexSource>&);
-    };
-
-}
-
-#endif
diff --git a/src/agg/agg_conv_curve.h b/src/agg/agg_conv_curve.h
deleted file mode 100644
index 1280903c0..000000000
--- a/src/agg/agg_conv_curve.h
+++ /dev/null
@@ -1,206 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_CONV_CURVE_INCLUDED
-#define AGG_CONV_CURVE_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_curves.h"
-
-namespace agg
-{
-
-
-    //---------------------------------------------------------------conv_curve
-    // Curve converter class. Any path storage can have Bezier curves defined 
-    // by their control points. There're two types of curves supported: curve3 
-    // and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control
-    // point. Curve4 has 2 control points (4 points in total) and can be used
-    // to interpolate more complicated curves. Curve4, unlike curve3 can be used 
-    // to approximate arcs, both circular and elliptical. Curves are approximated 
-    // with straight lines and one of the approaches is just to store the whole 
-    // sequence of vertices that approximate our curve. It takes additional 
-    // memory, and at the same time the consecutive vertices can be calculated 
-    // on demand. 
-    //
-    // Initially, path storages are not suppose to keep all the vertices of the
-    // curves (although, nothing prevents us from doing so). Instead, path_storage
-    // keeps only vertices, needed to calculate a curve on demand. Those vertices
-    // are marked with special commands. So, if the path_storage contains curves 
-    // (which are not real curves yet), and we render this storage directly, 
-    // all we will see is only 2 or 3 straight line segments (for curve3 and 
-    // curve4 respectively). If we need to see real curves drawn we need to 
-    // include this class into the conversion pipeline. 
-    //
-    // Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4 
-    // and converts these vertices into a move_to/line_to sequence. 
-    //-----------------------------------------------------------------------
-    template<class VertexSource, 
-             class Curve3=curve3, 
-             class Curve4=curve4> class conv_curve
-    {
-    public:
-        typedef Curve3 curve3_type;
-        typedef Curve4 curve4_type;
-        typedef conv_curve<VertexSource, Curve3, Curve4> self_type;
-
-        explicit conv_curve(VertexSource& source) :
-          m_source(&source), m_last_x(0.0), m_last_y(0.0) {}
-        void attach(VertexSource& source) { m_source = &source; }
-
-        void approximation_method(curve_approximation_method_e v) 
-        { 
-            m_curve3.approximation_method(v);
-            m_curve4.approximation_method(v);
-        }
-
-        curve_approximation_method_e approximation_method() const 
-        { 
-            return m_curve4.approximation_method();
-        }
-
-        void approximation_scale(double s) 
-        { 
-            m_curve3.approximation_scale(s); 
-            m_curve4.approximation_scale(s); 
-        }
-
-        double approximation_scale() const 
-        { 
-            return m_curve4.approximation_scale();  
-        }
-
-        void angle_tolerance(double v) 
-        { 
-            m_curve3.angle_tolerance(v); 
-            m_curve4.angle_tolerance(v); 
-        }
-
-        double angle_tolerance() const 
-        { 
-            return m_curve4.angle_tolerance();  
-        }
-
-        void cusp_limit(double v) 
-        { 
-            m_curve3.cusp_limit(v); 
-            m_curve4.cusp_limit(v); 
-        }
-
-        double cusp_limit() const 
-        { 
-            return m_curve4.cusp_limit();  
-        }
-
-        void     rewind(unsigned path_id); 
-        unsigned vertex(double* x, double* y);
-
-    private:
-        conv_curve(const self_type&);
-        const self_type& operator = (const self_type&);
-
-        VertexSource* m_source;
-        double        m_last_x;
-        double        m_last_y;
-        curve3_type   m_curve3;
-        curve4_type   m_curve4;
-    };
-
-
-
-    //------------------------------------------------------------------------
-    template<class VertexSource, class Curve3, class Curve4>
-    void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id)
-    {
-        m_source->rewind(path_id);
-        m_last_x = 0.0;
-        m_last_y = 0.0;
-        m_curve3.reset();
-        m_curve4.reset();
-    }
-
-
-    //------------------------------------------------------------------------
-    template<class VertexSource, class Curve3, class Curve4>
-    unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y)
-    {
-        if(!is_stop(m_curve3.vertex(x, y)))
-        {
-            m_last_x = *x;
-            m_last_y = *y;
-            return path_cmd_line_to;
-        }
-
-        if(!is_stop(m_curve4.vertex(x, y)))
-        {
-            m_last_x = *x;
-            m_last_y = *y;
-            return path_cmd_line_to;
-        }
-
-        double ct2_x;
-        double ct2_y;
-        double end_x;
-        double end_y;
-
-        unsigned cmd = m_source->vertex(x, y);
-        switch(cmd)
-        {
-        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);
-
-            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;
-
-        case path_cmd_curve4:
-            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);
-
-            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;
-    }
-
-
-}
-
-
-
-#endif
diff --git a/src/agg/agg_conv_stroke.h b/src/agg/agg_conv_stroke.h
deleted file mode 100644
index 271310078..000000000
--- a/src/agg/agg_conv_stroke.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_CONV_STROKE_INCLUDED
-#define AGG_CONV_STROKE_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_vcgen_stroke.h"
-#include "agg_conv_adaptor_vcgen.h"
-
-namespace agg
-{
-
-    //-------------------------------------------------------------conv_stroke
-    template<class VertexSource, class Markers=null_markers> 
-    struct conv_stroke : 
-    public conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>
-    {
-        typedef Markers marker_type;
-        typedef conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers> base_type;
-
-        conv_stroke(VertexSource& vs) : 
-            conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>(vs)
-        {
-        }
-
-        void line_cap(line_cap_e lc)     { base_type::generator().line_cap(lc);  }
-        void line_join(line_join_e lj)   { base_type::generator().line_join(lj); }
-        void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
-
-        line_cap_e   line_cap()   const { return base_type::generator().line_cap();  }
-        line_join_e  line_join()  const { return base_type::generator().line_join(); }
-        inner_join_e inner_join() const { return base_type::generator().inner_join(); }
-
-        void width(double w) { base_type::generator().width(w); }
-        void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
-        void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
-        void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
-        void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
-
-        double width() const { return base_type::generator().width(); }
-        double miter_limit() const { return base_type::generator().miter_limit(); }
-        double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
-        double approximation_scale() const { return base_type::generator().approximation_scale(); }
-
-        void shorten(double s) { base_type::generator().shorten(s); }
-        double shorten() const { return base_type::generator().shorten(); }
-
-    private:
-       conv_stroke(const conv_stroke<VertexSource, Markers>&);
-       const conv_stroke<VertexSource, Markers>& 
-           operator = (const conv_stroke<VertexSource, Markers>&);
-
-    };
-
-}
-
-#endif
diff --git a/src/agg/agg_conv_transform.h b/src/agg/agg_conv_transform.h
index 33c19b6e2..0c88a245b 100644
--- a/src/agg/agg_conv_transform.h
+++ b/src/agg/agg_conv_transform.h
@@ -1,27 +1,21 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class conv_transform
+//
 //----------------------------------------------------------------------------
-
 #ifndef AGG_CONV_TRANSFORM_INCLUDED
 #define AGG_CONV_TRANSFORM_INCLUDED
 
@@ -35,7 +29,7 @@ namespace agg
     template<class VertexSource, class Transformer=trans_affine> class conv_transform
     {
     public:
-        conv_transform(VertexSource& source, const Transformer& tr) :
+        conv_transform(VertexSource& source, Transformer& tr) :
             m_source(&source), m_trans(&tr) {}
         void attach(VertexSource& source) { m_source = &source; }
 
@@ -54,7 +48,7 @@ namespace agg
             return cmd;
         }
 
-        void transformer(const Transformer& tr)
+        void transformer(Transformer& tr)
         {
             m_trans = &tr;
         }
@@ -65,7 +59,7 @@ namespace agg
             operator = (const conv_transform<VertexSource>&);
 
         VertexSource*      m_source;
-        const Transformer* m_trans;
+        Transformer* m_trans;
     };
 
 
diff --git a/src/agg/agg_curves.h b/src/agg/agg_curves.h
deleted file mode 100644
index 25845cab3..000000000
--- a/src/agg/agg_curves.h
+++ /dev/null
@@ -1,701 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_CURVES_INCLUDED
-#define AGG_CURVES_INCLUDED
-
-#include "agg_array.h"
-
-namespace agg
-{
-
-    // See Implementation agg_curves.cpp
-
-    //--------------------------------------------curve_approximation_method_e
-    enum curve_approximation_method_e
-    {
-        curve_inc,
-        curve_div
-    };
-    
-    //--------------------------------------------------------------curve3_inc
-    class curve3_inc
-    {
-    public:
-        curve3_inc() :
-          m_num_steps(0), m_step(0), m_scale(1.0) { }
-
-        curve3_inc(double x1, double y1, 
-                   double x2, double y2, 
-                   double x3, double y3) :
-            m_num_steps(0), m_step(0), m_scale(1.0) 
-        { 
-            init(x1, y1, x2, y2, x3, y3);
-        }
-
-        void reset() { m_num_steps = 0; m_step = -1; }
-        void init(double x1, double y1, 
-                  double x2, double y2, 
-                  double x3, double y3);
-
-        void approximation_method(curve_approximation_method_e) {}
-        curve_approximation_method_e approximation_method() const { return curve_inc; }
-
-        void approximation_scale(double s);
-        double approximation_scale() const;
-
-        void angle_tolerance(double) {}
-        double angle_tolerance() const { return 0.0; }
-
-        void cusp_limit(double) {}
-        double cusp_limit() const { return 0.0; }
-
-        void     rewind(unsigned path_id);
-        unsigned vertex(double* x, double* y);
-
-    private:
-        int      m_num_steps;
-        int      m_step;
-        double   m_scale;
-        double   m_start_x; 
-        double   m_start_y;
-        double   m_end_x; 
-        double   m_end_y;
-        double   m_fx; 
-        double   m_fy;
-        double   m_dfx; 
-        double   m_dfy;
-        double   m_ddfx; 
-        double   m_ddfy;
-        double   m_saved_fx; 
-        double   m_saved_fy;
-        double   m_saved_dfx; 
-        double   m_saved_dfy;
-    };
-
-
-
-
-
-    //-------------------------------------------------------------curve3_div
-    class curve3_div
-    {
-    public:
-        curve3_div() : 
-            m_approximation_scale(1.0),
-            m_angle_tolerance(0.0),
-            m_count(0)
-        {}
-
-        curve3_div(double x1, double y1, 
-                   double x2, double y2, 
-                   double x3, double y3) :
-            m_approximation_scale(1.0),
-            m_angle_tolerance(0.0),
-            m_count(0)
-        { 
-            init(x1, y1, x2, y2, x3, y3);
-        }
-
-        void reset() { m_points.remove_all(); m_count = 0; }
-        void init(double x1, double y1, 
-                  double x2, double y2, 
-                  double x3, double y3);
-
-        void approximation_method(curve_approximation_method_e) {}
-        curve_approximation_method_e approximation_method() const { return curve_div; }
-
-        void approximation_scale(double s) { m_approximation_scale = s; }
-        double approximation_scale() const { return m_approximation_scale;  }
-
-        void angle_tolerance(double a) { m_angle_tolerance = a; }
-        double angle_tolerance() const { return m_angle_tolerance;  }
-
-        void cusp_limit(double) {}
-        double cusp_limit() const { return 0.0; }
-
-        void rewind(unsigned)
-        {
-            m_count = 0;
-        }
-
-        unsigned vertex(double* x, double* y)
-        {
-            if(m_count >= m_points.size()) return path_cmd_stop;
-            const point_d& p = m_points[m_count++];
-            *x = p.x;
-            *y = p.y;
-            return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
-        }
-
-    private:
-        void bezier(double x1, double y1, 
-                    double x2, double y2, 
-                    double x3, double y3);
-        void recursive_bezier(double x1, double y1, 
-                              double x2, double y2, 
-                              double x3, double y3,
-                              unsigned level);
-
-        double               m_approximation_scale;
-        double               m_distance_tolerance_square;
-        double               m_angle_tolerance;
-        unsigned             m_count;
-        pod_bvector<point_d> m_points;
-    };
-
-
-
-
-
-
-
-    //-------------------------------------------------------------curve4_points
-    struct curve4_points
-    {
-        double cp[8];
-        curve4_points() {}
-        curve4_points(double x1, double y1,
-                      double x2, double y2,
-                      double x3, double y3,
-                      double x4, double y4)
-        {
-            cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
-            cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
-        }
-        void init(double x1, double y1,
-                  double x2, double y2,
-                  double x3, double y3,
-                  double x4, double y4)
-        {
-            cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
-            cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
-        }
-        double  operator [] (unsigned i) const { return cp[i]; }
-        double& operator [] (unsigned i)       { return cp[i]; }
-    };
-
-
-
-    //-------------------------------------------------------------curve4_inc
-    class curve4_inc
-    {
-    public:
-        curve4_inc() :
-            m_num_steps(0), m_step(0), m_scale(1.0) { }
-
-        curve4_inc(double x1, double y1, 
-                   double x2, double y2, 
-                   double x3, double y3,
-                   double x4, double y4) :
-            m_num_steps(0), m_step(0), m_scale(1.0) 
-        { 
-            init(x1, y1, x2, y2, x3, y3, x4, y4);
-        }
-
-        curve4_inc(const curve4_points& cp) :
-            m_num_steps(0), m_step(0), m_scale(1.0) 
-        { 
-            init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
-        }
-
-        void reset() { m_num_steps = 0; m_step = -1; }
-        void init(double x1, double y1, 
-                  double x2, double y2, 
-                  double x3, double y3,
-                  double x4, double y4);
-
-        void init(const curve4_points& cp)
-        {
-            init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
-        }
-
-        void approximation_method(curve_approximation_method_e) {}
-        curve_approximation_method_e approximation_method() const { return curve_inc; }
-
-        void approximation_scale(double s);
-        double approximation_scale() const;
-
-        void angle_tolerance(double) {}
-        double angle_tolerance() const { return 0.0; }
-
-        void cusp_limit(double) {}
-        double cusp_limit() const { return 0.0; }
-
-        void     rewind(unsigned path_id);
-        unsigned vertex(double* x, double* y);
-
-    private:
-        int      m_num_steps;
-        int      m_step;
-        double   m_scale;
-        double   m_start_x; 
-        double   m_start_y;
-        double   m_end_x; 
-        double   m_end_y;
-        double   m_fx; 
-        double   m_fy;
-        double   m_dfx; 
-        double   m_dfy;
-        double   m_ddfx; 
-        double   m_ddfy;
-        double   m_dddfx; 
-        double   m_dddfy;
-        double   m_saved_fx; 
-        double   m_saved_fy;
-        double   m_saved_dfx; 
-        double   m_saved_dfy;
-        double   m_saved_ddfx; 
-        double   m_saved_ddfy;
-    };
-
-
-
-    //-------------------------------------------------------catrom_to_bezier
-    inline curve4_points catrom_to_bezier(double x1, double y1, 
-                                          double x2, double y2, 
-                                          double x3, double y3,
-                                          double x4, double y4)
-    {
-        // Trans. matrix Catmull-Rom to Bezier
-        //
-        //  0       1       0       0
-        //  -1/6    1       1/6     0
-        //  0       1/6     1       -1/6
-        //  0       0       1       0
-        //
-        return curve4_points(
-            x2,
-            y2,
-            (-x1 + 6*x2 + x3) / 6,
-            (-y1 + 6*y2 + y3) / 6,
-            ( x2 + 6*x3 - x4) / 6,
-            ( y2 + 6*y3 - y4) / 6,
-            x3,
-            y3);
-    }
-
-
-    //-----------------------------------------------------------------------
-    inline curve4_points
-    catrom_to_bezier(const curve4_points& cp)
-    {
-        return catrom_to_bezier(cp[0], cp[1], cp[2], cp[3], 
-                                cp[4], cp[5], cp[6], cp[7]);
-    }
-
-
-
-    //-----------------------------------------------------ubspline_to_bezier
-    inline curve4_points ubspline_to_bezier(double x1, double y1, 
-                                            double x2, double y2, 
-                                            double x3, double y3,
-                                            double x4, double y4)
-    {
-        // Trans. matrix Uniform BSpline to Bezier
-        //
-        //  1/6     4/6     1/6     0
-        //  0       4/6     2/6     0
-        //  0       2/6     4/6     0
-        //  0       1/6     4/6     1/6
-        //
-        return curve4_points(
-            (x1 + 4*x2 + x3) / 6,
-            (y1 + 4*y2 + y3) / 6,
-            (4*x2 + 2*x3) / 6,
-            (4*y2 + 2*y3) / 6,
-            (2*x2 + 4*x3) / 6,
-            (2*y2 + 4*y3) / 6,
-            (x2 + 4*x3 + x4) / 6,
-            (y2 + 4*y3 + y4) / 6);
-    }
-
-
-    //-----------------------------------------------------------------------
-    inline curve4_points 
-    ubspline_to_bezier(const curve4_points& cp)
-    {
-        return ubspline_to_bezier(cp[0], cp[1], cp[2], cp[3], 
-                                  cp[4], cp[5], cp[6], cp[7]);
-    }
-
-
-
-
-    //------------------------------------------------------hermite_to_bezier
-    inline curve4_points hermite_to_bezier(double x1, double y1, 
-                                           double x2, double y2, 
-                                           double x3, double y3,
-                                           double x4, double y4)
-    {
-        // Trans. matrix Hermite to Bezier
-        //
-        //  1       0       0       0
-        //  1       0       1/3     0
-        //  0       1       0       -1/3
-        //  0       1       0       0
-        //
-        return curve4_points(
-            x1,
-            y1,
-            (3*x1 + x3) / 3,
-            (3*y1 + y3) / 3,
-            (3*x2 - x4) / 3,
-            (3*y2 - y4) / 3,
-            x2,
-            y2);
-    }
-
-
-
-    //-----------------------------------------------------------------------
-    inline curve4_points 
-    hermite_to_bezier(const curve4_points& cp)
-    {
-        return hermite_to_bezier(cp[0], cp[1], cp[2], cp[3], 
-                                 cp[4], cp[5], cp[6], cp[7]);
-    }
-
-
-    //-------------------------------------------------------------curve4_div
-    class curve4_div
-    {
-    public:
-        curve4_div() : 
-            m_approximation_scale(1.0),
-            m_angle_tolerance(0.0),
-            m_cusp_limit(0.0),
-            m_count(0)
-        {}
-
-        curve4_div(double x1, double y1, 
-                   double x2, double y2, 
-                   double x3, double y3,
-                   double x4, double y4) :
-            m_approximation_scale(1.0),
-            m_angle_tolerance(0.0),
-            m_cusp_limit(0.0),
-            m_count(0)
-        { 
-            init(x1, y1, x2, y2, x3, y3, x4, y4);
-        }
-
-        curve4_div(const curve4_points& cp) :
-            m_approximation_scale(1.0),
-            m_angle_tolerance(0.0),
-            m_count(0)
-        { 
-            init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
-        }
-
-        void reset() { m_points.remove_all(); m_count = 0; }
-        void init(double x1, double y1, 
-                  double x2, double y2, 
-                  double x3, double y3,
-                  double x4, double y4);
-
-        void init(const curve4_points& cp)
-        {
-            init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
-        }
-
-        void approximation_method(curve_approximation_method_e) {}
-
-        curve_approximation_method_e approximation_method() const 
-        { 
-            return curve_div; 
-        }
-
-        void approximation_scale(double s) { m_approximation_scale = s; }
-        double approximation_scale() const { return m_approximation_scale;  }
-
-        void angle_tolerance(double a) { m_angle_tolerance = a; }
-        double angle_tolerance() const { return m_angle_tolerance;  }
-
-        void cusp_limit(double v) 
-        { 
-            m_cusp_limit = (v == 0.0) ? 0.0 : pi - v; 
-        }
-
-        double cusp_limit() const 
-        { 
-            return (m_cusp_limit == 0.0) ? 0.0 : pi - m_cusp_limit; 
-        }
-
-        void rewind(unsigned)
-        {
-            m_count = 0;
-        }
-
-        unsigned vertex(double* x, double* y)
-        {
-            if(m_count >= m_points.size()) return path_cmd_stop;
-            const point_d& p = m_points[m_count++];
-            *x = p.x;
-            *y = p.y;
-            return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
-        }
-
-    private:
-        void bezier(double x1, double y1, 
-                    double x2, double y2, 
-                    double x3, double y3, 
-                    double x4, double y4);
-
-        void recursive_bezier(double x1, double y1, 
-                              double x2, double y2, 
-                              double x3, double y3, 
-                              double x4, double y4,
-                              unsigned level);
-
-        double               m_approximation_scale;
-        double               m_distance_tolerance_square;
-        double               m_angle_tolerance;
-        double               m_cusp_limit;
-        unsigned             m_count;
-        pod_bvector<point_d> m_points;
-    };
-
-
-    //-----------------------------------------------------------------curve3
-    class curve3
-    {
-    public:
-        curve3() : m_approximation_method(curve_div) {}
-        curve3(double x1, double y1, 
-               double x2, double y2, 
-               double x3, double y3) :
-            m_approximation_method(curve_div)
-        { 
-            init(x1, y1, x2, y2, x3, y3);
-        }
-
-        void reset() 
-        { 
-            m_curve_inc.reset();
-            m_curve_div.reset();
-        }
-
-        void init(double x1, double y1, 
-                  double x2, double y2, 
-                  double x3, double y3)
-        {
-            if(m_approximation_method == curve_inc) 
-            {
-                m_curve_inc.init(x1, y1, x2, y2, x3, y3);
-            }
-            else
-            {
-                m_curve_div.init(x1, y1, x2, y2, x3, y3);
-            }
-        }
-
-        void approximation_method(curve_approximation_method_e v) 
-        { 
-            m_approximation_method = v; 
-        }
-
-        curve_approximation_method_e approximation_method() const 
-        { 
-            return m_approximation_method; 
-        }
-
-        void approximation_scale(double s) 
-        { 
-            m_curve_inc.approximation_scale(s);
-            m_curve_div.approximation_scale(s);
-        }
-
-        double approximation_scale() const 
-        { 
-            return m_curve_inc.approximation_scale(); 
-        }
-
-        void angle_tolerance(double a) 
-        { 
-            m_curve_div.angle_tolerance(a); 
-        }
-
-        double angle_tolerance() const 
-        { 
-            return m_curve_div.angle_tolerance(); 
-        }
-
-        void cusp_limit(double v) 
-        { 
-            m_curve_div.cusp_limit(v); 
-        }
-
-        double cusp_limit() const 
-        { 
-            return m_curve_div.cusp_limit();  
-        }
-
-        void rewind(unsigned path_id)
-        {
-            if(m_approximation_method == curve_inc) 
-            {
-                m_curve_inc.rewind(path_id);
-            }
-            else
-            {
-                m_curve_div.rewind(path_id);
-            }
-        }
-
-        unsigned vertex(double* x, double* y)
-        {
-            if(m_approximation_method == curve_inc) 
-            {
-                return m_curve_inc.vertex(x, y);
-            }
-            return m_curve_div.vertex(x, y);
-        }
-
-    private:
-        curve3_inc m_curve_inc;
-        curve3_div m_curve_div;
-        curve_approximation_method_e m_approximation_method;
-    };
-
-
-
-
-
-    //-----------------------------------------------------------------curve4
-    class curve4
-    {
-    public:
-        curve4() : m_approximation_method(curve_div) {}
-        curve4(double x1, double y1, 
-               double x2, double y2, 
-               double x3, double y3,
-               double x4, double y4) : 
-            m_approximation_method(curve_div)
-        { 
-            init(x1, y1, x2, y2, x3, y3, x4, y4);
-        }
-
-        curve4(const curve4_points& cp) :
-            m_approximation_method(curve_div)
-        { 
-            init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
-        }
-
-        void reset() 
-        { 
-            m_curve_inc.reset();
-            m_curve_div.reset();
-        }
-
-        void init(double x1, double y1, 
-                  double x2, double y2, 
-                  double x3, double y3,
-                  double x4, double y4)
-        {
-            if(m_approximation_method == curve_inc) 
-            {
-                m_curve_inc.init(x1, y1, x2, y2, x3, y3, x4, y4);
-            }
-            else
-            {
-                m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4);
-            }
-        }
-
-        void init(const curve4_points& cp)
-        {
-            init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
-        }
-
-        void approximation_method(curve_approximation_method_e v) 
-        { 
-            m_approximation_method = v; 
-        }
-
-        curve_approximation_method_e approximation_method() const 
-        { 
-            return m_approximation_method; 
-        }
-
-        void approximation_scale(double s) 
-        { 
-            m_curve_inc.approximation_scale(s);
-            m_curve_div.approximation_scale(s);
-        }
-        double approximation_scale() const { return m_curve_inc.approximation_scale(); }
-
-        void angle_tolerance(double v) 
-        { 
-            m_curve_div.angle_tolerance(v); 
-        }
-
-        double angle_tolerance() const 
-        { 
-            return m_curve_div.angle_tolerance();  
-        }
-
-        void cusp_limit(double v) 
-        { 
-            m_curve_div.cusp_limit(v); 
-        }
-
-        double cusp_limit() const 
-        { 
-            return m_curve_div.cusp_limit();  
-        }
-
-        void rewind(unsigned path_id)
-        {
-            if(m_approximation_method == curve_inc) 
-            {
-                m_curve_inc.rewind(path_id);
-            }
-            else
-            {
-                m_curve_div.rewind(path_id);
-            }
-        }
-
-        unsigned vertex(double* x, double* y)
-        {
-            if(m_approximation_method == curve_inc) 
-            {
-                return m_curve_inc.vertex(x, y);
-            }
-            return m_curve_div.vertex(x, y);
-        }
-
-    private:
-        curve4_inc m_curve_inc;
-        curve4_div m_curve_div;
-        curve_approximation_method_e m_approximation_method;
-    };
-
-
-
-
-}
-
-#endif
diff --git a/src/agg/agg_gamma_functions.h b/src/agg/agg_gamma_functions.h
index fa38a45ad..5d720daa9 100644
--- a/src/agg/agg_gamma_functions.h
+++ b/src/agg/agg_gamma_functions.h
@@ -1,25 +1,16 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
 
 #ifndef AGG_GAMMA_FUNCTIONS_INCLUDED
@@ -124,6 +115,15 @@ namespace agg
         double m_mul;
     };
 
+    inline double sRGB_to_linear(double x)
+    {
+        return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4);
+    }
+
+    inline double linear_to_sRGB(double x)
+    {
+        return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055);
+    }
 }
 
 #endif
diff --git a/src/agg/agg_gamma_lut.h b/src/agg/agg_gamma_lut.h
index 5240da798..e30873632 100644
--- a/src/agg/agg_gamma_lut.h
+++ b/src/agg/agg_gamma_lut.h
@@ -1,25 +1,16 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
 
 #ifndef AGG_GAMMA_LUT_INCLUDED
@@ -27,6 +18,7 @@
 
 #include <math.h>
 #include "agg_basics.h"
+#include "agg_gamma_functions.h"
 
 namespace agg
 {
@@ -125,6 +117,184 @@ namespace agg
         HiResT* m_dir_gamma;
         LoResT* m_inv_gamma;
     };
+
+    //
+    // sRGB support classes
+    //
+
+    // sRGB_lut - implements sRGB conversion for the various types.
+    // Base template is undefined, specializations are provided below.
+    template<class LinearType>
+    class sRGB_lut;
+
+    template<>
+    class sRGB_lut<float>
+    {
+    public:
+		sRGB_lut()
+		{
+			// Generate lookup tables.
+			for (int i = 0; i <= 255; ++i)
+			{
+				m_dir_table[i] = float(sRGB_to_linear(i / 255.0));
+			}
+			for (int i = 0; i <= 65535; ++i)
+			{
+				m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 65535.0));
+			}
+		}
+
+		float dir(int8u v) const
+		{
+			return m_dir_table[v];
+		}
+
+		int8u inv(float v) const
+		{
+			return m_inv_table[int16u(0.5 + v * 65535)];
+		}
+
+	private:
+		float m_dir_table[256];
+		int8u m_inv_table[65536];
+    };
+
+    template<>
+    class sRGB_lut<int16u>
+    {
+    public:
+        sRGB_lut()
+        {
+            // Generate lookup tables.
+            for (int i = 0; i <= 255; ++i)
+            {
+                m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0));
+            }
+			for (int i = 0; i <= 65535; ++i)
+			{
+				m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 65535.0));
+			}
+		}
+
+		int16u dir(int8u v) const
+		{
+			return m_dir_table[v];
+		}
+
+		int8u inv(int16u v) const
+		{
+			return m_inv_table[v];
+		}
+
+	private:
+		int16u m_dir_table[256];
+		int8u m_inv_table[65536];
+	};
+
+    template<>
+    class sRGB_lut<int8u>
+    {
+    public:
+        sRGB_lut()
+        {
+            // Generate lookup tables. 
+            for (int i = 0; i <= 255; ++i)
+            {
+                m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0));
+                m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0));
+            }
+        }
+
+		int8u dir(int8u v) const
+		{
+			return m_dir_table[v];
+		}
+
+		int8u inv(int8u v) const
+        {
+            return m_inv_table[v];
+        }
+
+	private:
+		int8u m_dir_table[256];
+		int8u m_inv_table[256];
+	};
+
+    // Common base class for sRGB_conv objects. Defines an internal 
+    // sRGB_lut object so that users don't have to.
+    template<class T>
+    class sRGB_conv_base
+    {
+    public:
+        static T rgb_from_sRGB(int8u x)
+        {
+            return lut.dir(x);
+        }
+
+        static int8u rgb_to_sRGB(T x)
+        {
+            return lut.inv(x);
+        }
+
+    private:
+        static sRGB_lut<T> lut;
+    };
+
+    // Definition of sRGB_conv_base::lut. Due to the fact that this a template, 
+    // we don't need to place the definition in a cpp file. Hurrah.
+    template<class T>
+    sRGB_lut<T> sRGB_conv_base<T>::lut;
+
+    // Wrapper for sRGB-linear conversion. 
+    // Base template is undefined, specializations are provided below.
+    template<class T>
+    class sRGB_conv;
+
+    template<>
+    class sRGB_conv<float> : public sRGB_conv_base<float>
+    {
+    public:
+        static float alpha_from_sRGB(int8u x)
+        {
+			static const double y = 1 / 255.0;
+            return float(x * y);
+        }
+
+        static int8u alpha_to_sRGB(float x)
+        {
+            return int8u(0.5 + x * 255);
+        }
+    };
+
+    template<>
+    class sRGB_conv<int16u> : public sRGB_conv_base<int16u>
+    {
+    public:
+        static int16u alpha_from_sRGB(int8u x)
+        {
+            return (x << 8) | x;
+        }
+
+        static int8u alpha_to_sRGB(int16u x)
+        {
+            return x >> 8;
+        }
+    };
+
+    template<>
+    class sRGB_conv<int8u> : public sRGB_conv_base<int8u>
+    {
+    public:
+        static int8u alpha_from_sRGB(int8u x)
+        {
+            return x;
+        }
+
+        static int8u alpha_to_sRGB(int8u x)
+        {
+            return x;
+        }
+    };
 }
 
 #endif
diff --git a/src/agg/agg_math.h b/src/agg/agg_math.h
index 4e512facb..2ec49cf3f 100644
--- a/src/agg/agg_math.h
+++ b/src/agg/agg_math.h
@@ -1,25 +1,16 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
 // Bessel function (besj) was adapted for use in AGG library by Andy Wilk 
 // Contact: castor.vulgaris@gmail.com
diff --git a/src/agg/agg_math_stroke.h b/src/agg/agg_math_stroke.h
deleted file mode 100644
index ad09af27e..000000000
--- a/src/agg/agg_math_stroke.h
+++ /dev/null
@@ -1,531 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_STROKE_MATH_INCLUDED
-#define AGG_STROKE_MATH_INCLUDED
-
-#include "agg_math.h"
-#include "agg_vertex_sequence.h"
-
-namespace agg
-{
-    //-------------------------------------------------------------line_cap_e
-    enum line_cap_e
-    {
-        butt_cap,
-        square_cap,
-        round_cap
-    };
-
-    //------------------------------------------------------------line_join_e
-    enum line_join_e
-    {
-        miter_join         = 0,
-        miter_join_revert  = 1,
-        round_join         = 2,
-        bevel_join         = 3,
-        miter_join_round   = 4
-    };
-
-
-    //-----------------------------------------------------------inner_join_e
-    enum inner_join_e
-    {
-        inner_bevel,
-        inner_miter,
-        inner_jag,
-        inner_round
-    };
-
-    //------------------------------------------------------------math_stroke
-    template<class VertexConsumer> class math_stroke
-    {
-    public:
-        typedef typename VertexConsumer::value_type coord_type;
-
-        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& vc,
-                      const vertex_dist& v0, 
-                      const vertex_dist& v1, 
-                      double len);
-
-        void calc_join(VertexConsumer& vc,
-                       const vertex_dist& v0, 
-                       const vertex_dist& v1, 
-                       const vertex_dist& v2,
-                       double len1, 
-                       double len2);
-
-    private:
-        AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y)
-        {
-            vc.add(coord_type(x, y));
-        }
-
-        void calc_arc(VertexConsumer& vc,
-                      double x,   double y, 
-                      double dx1, double dy1, 
-                      double dx2, double dy2);
-
-        void calc_miter(VertexConsumer& vc,
-                        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 mlimit,
-                        double dbevel);
-
-        double       m_width;
-        double       m_width_abs;
-        double       m_width_eps;
-        int          m_width_sign;
-        double       m_miter_limit;
-        double       m_inner_miter_limit;
-        double       m_approx_scale;
-        line_cap_e   m_line_cap;
-        line_join_e  m_line_join;
-        inner_join_e m_inner_join;
-    };
-
-    //-----------------------------------------------------------------------
-    template<class VC> math_stroke<VC>::math_stroke() :
-        m_width(0.5),
-        m_width_abs(0.5),
-        m_width_eps(0.5/1024.0),
-        m_width_sign(1),
-        m_miter_limit(4.0),
-        m_inner_miter_limit(1.01),
-        m_approx_scale(1.0),
-        m_line_cap(butt_cap),
-        m_line_join(miter_join),
-        m_inner_join(inner_miter)
-    {
-    }
-
-    //-----------------------------------------------------------------------
-    template<class VC> void math_stroke<VC>::width(double w)
-    { 
-        m_width = w * 0.5; 
-        if(m_width < 0)
-        {
-            m_width_abs  = -m_width;
-            m_width_sign = -1;
-        }
-        else
-        {
-            m_width_abs  = m_width;
-            m_width_sign = 1;
-        }
-        m_width_eps = m_width / 1024.0;
-    }
-
-    //-----------------------------------------------------------------------
-    template<class VC> void math_stroke<VC>::miter_limit_theta(double t)
-    { 
-        m_miter_limit = 1.0 / sin(t * 0.5) ;
-    }
-
-    //-----------------------------------------------------------------------
-    template<class VC> 
-    void math_stroke<VC>::calc_arc(VC& vc,
-                                   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;
-
-        da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
-
-        add_vertex(vc, x + dx1, y + dy1);
-        if(m_width_sign > 0)
-        {
-            if(a1 > a2) a2 += 2 * pi;
-            n = int((a2 - a1) / da);
-            da = (a2 - a1) / (n + 1);
-            a1 += da;
-            for(i = 0; i < n; i++)
-            {
-                add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
-                a1 += da;
-            }
-        }
-        else
-        {
-            if(a1 < a2) a2 -= 2 * pi;
-            n = int((a1 - a2) / da);
-            da = (a1 - a2) / (n + 1);
-            a1 -= da;
-            for(i = 0; i < n; i++)
-            {
-                add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
-                a1 -= da;
-            }
-        }
-        add_vertex(vc, x + dx2, y + dy2);
-    }
-
-    //-----------------------------------------------------------------------
-    template<class VC> 
-    void math_stroke<VC>::calc_miter(VC& vc,
-                                     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 mlimit,
-                                     double dbevel)
-    {
-        double xi  = v1.x;
-        double yi  = v1.y;
-        double di  = 1;
-        double lim = m_width_abs * mlimit;
-        bool miter_limit_exceeded = true; // Assume the worst
-        bool intersection_failed  = true; // Assume the worst
-
-        if(calc_intersection(v0.x + dx1, v0.y - dy1,
-                             v1.x + dx1, v1.y - dy1,
-                             v1.x + dx2, v1.y - dy2,
-                             v2.x + dx2, v2.y - dy2,
-                             &xi, &yi))
-        {
-            // Calculation of the intersection succeeded
-            //---------------------
-            di = calc_distance(v1.x, v1.y, xi, yi);
-            if(di <= lim)
-            {
-                // Inside the miter limit
-                //---------------------
-                add_vertex(vc, xi, yi);
-                miter_limit_exceeded = false;
-            }
-            intersection_failed = false;
-        }
-        else
-        {
-            // Calculation of the intersection failed, most probably
-            // the three points lie one straight line. 
-            // First check if v0 and v2 lie on the opposite sides of vector: 
-            // (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
-            // to the line determined by vertices v0 and v1.
-            // This condition determines whether the next line segments continues
-            // the previous one or goes back.
-            //----------------
-            double x2 = v1.x + dx1;
-            double y2 = v1.y - dy1;
-            if((cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) == 
-               (cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0))
-            {
-                // This case means that the next segment continues 
-                // the previous one (straight line)
-                //-----------------
-                add_vertex(vc, v1.x + dx1, v1.y - dy1);
-                miter_limit_exceeded = false;
-            }
-        }
-
-        if(miter_limit_exceeded)
-        {
-            // Miter limit exceeded
-            //------------------------
-            switch(lj)
-            {
-            case miter_join_revert:
-                // For the compatibility with SVG, PDF, etc, 
-                // we use a simple bevel join instead of
-                // "smart" bevel
-                //-------------------
-                add_vertex(vc, v1.x + dx1, v1.y - dy1);
-                add_vertex(vc, v1.x + dx2, v1.y - dy2);
-                break;
-
-            case miter_join_round:
-                calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
-                break;
-
-            default:
-                // If no miter-revert, calculate new dx1, dy1, dx2, dy2
-                //----------------
-                if(intersection_failed)
-                {
-                    mlimit *= m_width_sign;
-                    add_vertex(vc, v1.x + dx1 + dy1 * mlimit, 
-                                   v1.y - dy1 + dx1 * mlimit);
-                    add_vertex(vc, v1.x + dx2 - dy2 * mlimit, 
-                                   v1.y - dy2 - dx2 * mlimit);
-                }
-                else
-                {
-                    double x1 = v1.x + dx1;
-                    double y1 = v1.y - dy1;
-                    double x2 = v1.x + dx2;
-                    double y2 = v1.y - dy2;
-                    di = (lim - dbevel) / (di - dbevel);
-                    add_vertex(vc, x1 + (xi - x1) * di, 
-                                   y1 + (yi - y1) * di);
-                    add_vertex(vc, x2 + (xi - x2) * di, 
-                                   y2 + (yi - y2) * di);
-                }
-                break;
-            }
-        }
-    }
-
-    //--------------------------------------------------------stroke_calc_cap
-    template<class VC> 
-    void math_stroke<VC>::calc_cap(VC& vc,
-                                   const vertex_dist& v0, 
-                                   const vertex_dist& v1, 
-                                   double len)
-    {
-        vc.remove_all();
-
-        double dx1 = (v1.y - v0.y) / len;
-        double dy1 = (v1.x - v0.x) / len;
-        double dx2 = 0;
-        double dy2 = 0;
-
-        dx1 *= m_width;
-        dy1 *= m_width;
-
-        if(m_line_cap != round_cap)
-        {
-            if(m_line_cap == square_cap)
-            {
-                dx2 = dy1 * m_width_sign;
-                dy2 = dx1 * m_width_sign;
-            }
-            add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2);
-            add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2);
-        }
-        else
-        {
-            double da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
-            double a1;
-            int i;
-            int n = int(pi / da);
-
-            da = pi / (n + 1);
-            add_vertex(vc, v0.x - dx1, v0.y + dy1);
-            if(m_width_sign > 0)
-            {
-                a1 = atan2(dy1, -dx1);
-                a1 += da;
-                for(i = 0; i < n; i++)
-                {
-                    add_vertex(vc, 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++)
-                {
-                    add_vertex(vc, v0.x + cos(a1) * m_width, 
-                                   v0.y + sin(a1) * m_width);
-                    a1 -= da;
-                }
-            }
-            add_vertex(vc, v0.x + dx1, v0.y - dy1);
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    template<class VC> 
-    void math_stroke<VC>::calc_join(VC& vc,
-                                    const vertex_dist& v0, 
-                                    const vertex_dist& v1, 
-                                    const vertex_dist& v2,
-                                    double len1, 
-                                    double len2)
-    {
-        double dx1 = m_width * (v1.y - v0.y) / len1;
-        double dy1 = m_width * (v1.x - v0.x) / len1;
-        double dx2 = m_width * (v2.y - v1.y) / len2;
-        double dy2 = m_width * (v2.x - v1.x) / len2;
-
-        vc.remove_all();
-
-        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
-            //---------------
-            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
-                add_vertex(vc, v1.x + dx1, v1.y - dy1);
-                add_vertex(vc, v1.x + dx2, v1.y - dy2);
-                break;
-
-            case inner_miter:
-                calc_miter(vc,
-                           v0, v1, v2, dx1, dy1, dx2, dy2, 
-                           miter_join_revert, 
-                           limit, 0);
-                break;
-
-            case inner_jag:
-            case inner_round:
-                cp = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
-                if(cp < len1 * len1 && cp < len2 * len2)
-                {
-                    calc_miter(vc,
-                               v0, v1, v2, dx1, dy1, dx2, dy2, 
-                               miter_join_revert, 
-                               limit, 0);
-                }
-                else
-                {
-                    if(m_inner_join == inner_jag)
-                    {
-                        add_vertex(vc, v1.x + dx1, v1.y - dy1);
-                        add_vertex(vc, v1.x,       v1.y      );
-                        add_vertex(vc, v1.x + dx2, v1.y - dy2);
-                    }
-                    else
-                    {
-                        add_vertex(vc, v1.x + dx1, v1.y - dy1);
-                        add_vertex(vc, v1.x,       v1.y      );
-                        calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
-                        add_vertex(vc, v1.x,       v1.y      );
-                        add_vertex(vc, v1.x + dx2, v1.y - dy2);
-                    }
-                }
-                break;
-            }
-        }
-        else
-        {
-            // Outer join
-            //---------------
-
-            // Calculate the distance between v1 and 
-            // the central point of the bevel line segment
-            //---------------
-            double dx = (dx1 + dx2) / 2;
-            double dy = (dy1 + dy2) / 2;
-            double dbevel = sqrt(dx * dx + dy * dy);
-
-            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 collinear 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 
-                // add just one point. 
-                //
-                // The constant in the expression makes the result approximately 
-                // the same as in round joins and caps. You can safely comment 
-                // out this entire "if".
-                //-------------------
-                if(m_approx_scale * (m_width_abs - dbevel) < m_width_eps)
-                {
-                    if(calc_intersection(v0.x + dx1, v0.y - dy1,
-                                         v1.x + dx1, v1.y - dy1,
-                                         v1.x + dx2, v1.y - dy2,
-                                         v2.x + dx2, v2.y - dy2,
-                                         &dx, &dy))
-                    {
-                        add_vertex(vc, dx, dy);
-                    }
-                    else
-                    {
-                        add_vertex(vc, v1.x + dx1, v1.y - dy1);
-                    }
-                    return;
-                }
-            }
-
-            switch(m_line_join)
-            {
-            case miter_join:
-            case miter_join_revert:
-            case miter_join_round:
-                calc_miter(vc, 
-                           v0, v1, v2, dx1, dy1, dx2, dy2, 
-                           m_line_join, 
-                           m_miter_limit,
-                           dbevel);
-                break;
-
-            case round_join:
-                calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
-                break;
-
-            default: // Bevel join
-                add_vertex(vc, v1.x + dx1, v1.y - dy1);
-                add_vertex(vc, v1.x + dx2, v1.y - dy2);
-                break;
-            }
-        }
-    }
-
-
-
-
-}
-
-#endif
diff --git a/src/agg/agg_path_storage.h b/src/agg/agg_path_storage.h
index 7be7393c9..f55c89957 100644
--- a/src/agg/agg_path_storage.h
+++ b/src/agg/agg_path_storage.h
@@ -1,25 +1,16 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
 
 #ifndef AGG_PATH_STORAGE_INCLUDED
@@ -499,14 +490,14 @@ namespace agg
             m_stop(false)
         {}
 
-        poly_container_reverse_adaptor(const Container& data, bool closed) :
+        poly_container_reverse_adaptor(Container& data, bool closed) :
             m_container(&data), 
             m_index(-1),
             m_closed(closed),
             m_stop(false)
         {}
 
-        void init(const Container& data, bool closed)
+        void init(Container& data, bool closed)
         {
             m_container = &data;
             m_index = m_container->size() - 1;
@@ -540,7 +531,7 @@ namespace agg
         }
 
     private:
-        const Container* m_container;
+        Container* m_container;
         int  m_index;
         bool m_closed;
         bool m_stop;
@@ -844,6 +835,43 @@ namespace agg
         }
 
 
+        //--------------------------------------------------------------------
+        // If the end points of a path are very, very close then make them
+        // exactly equal so that the stroke converter is not confused.
+        //--------------------------------------------------------------------
+        unsigned align_path(unsigned idx = 0)
+        {
+            if (idx >= total_vertices() || !is_move_to(command(idx))) 
+            {
+                return total_vertices();
+            }
+
+            double start_x, start_y;
+            for (; idx < total_vertices() && is_move_to(command(idx)); ++idx)
+            {
+                vertex(idx, &start_x, &start_y);
+            }
+            while (idx < total_vertices() && is_drawing(command(idx)))
+                ++idx;
+
+            double x, y;
+            if (is_drawing(vertex(idx - 1, &x, &y)) &&
+                is_equal_eps(x, start_x, 1e-8) &&
+                is_equal_eps(y, start_y, 1e-8))
+            {
+                modify_vertex(idx - 1, start_x, start_y);
+            }
+
+            while (idx < total_vertices() && !is_move_to(command(idx)))
+                ++idx;
+            return idx;
+        }
+
+        void align_all_paths()
+        {
+            for (unsigned i = 0; i < total_vertices(); i = align_path(i));
+        }
+
 
     private:
         unsigned perceive_polygon_orientation(unsigned start, unsigned end);
diff --git a/src/agg/agg_pixfmt_base.h b/src/agg/agg_pixfmt_base.h
new file mode 100644
index 000000000..57ae19cfe
--- /dev/null
+++ b/src/agg/agg_pixfmt_base.h
@@ -0,0 +1,97 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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_BASE_INCLUDED
+#define AGG_PIXFMT_BASE_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_color_gray.h"
+#include "agg_color_rgba.h"
+
+namespace agg
+{
+    struct pixfmt_gray_tag
+    {
+    };
+
+    struct pixfmt_rgb_tag
+    {
+    };
+
+    struct pixfmt_rgba_tag
+    {
+    };
+
+    //--------------------------------------------------------------blender_base
+    template<class ColorT, class Order = void> 
+    struct blender_base
+    {
+        typedef ColorT color_type;
+        typedef Order order_type;
+        typedef typename color_type::value_type value_type;
+
+        static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full)
+        {
+            if (cover > cover_none)
+            {
+                rgba c(
+                    color_type::to_double(r), 
+                    color_type::to_double(g), 
+                    color_type::to_double(b), 
+                    color_type::to_double(a));
+
+                if (cover < cover_full)
+                {
+                    double x = double(cover) / cover_full;
+                    c.r *= x;
+                    c.g *= x;
+                    c.b *= x;
+                    c.a *= x;
+                }
+
+                return c;
+            }
+            else return rgba::no_color();
+        }
+
+        static rgba get(const value_type* p, cover_type cover = cover_full)
+        {
+            return get(
+                p[order_type::R], 
+                p[order_type::G], 
+                p[order_type::B], 
+                p[order_type::A], 
+                cover);
+        }
+
+        static void set(value_type* p, value_type r, value_type g, value_type b, value_type a)
+        {
+            p[order_type::R] = r;
+            p[order_type::G] = g;
+            p[order_type::B] = b;
+            p[order_type::A] = a;
+        }
+
+        static void set(value_type* p, const rgba& c)
+        {
+            p[order_type::R] = color_type::from_double(c.r);
+            p[order_type::G] = color_type::from_double(c.g);
+            p[order_type::B] = color_type::from_double(c.b);
+            p[order_type::A] = color_type::from_double(c.a);
+        }
+    };
+}
+
+#endif
diff --git a/src/agg/agg_pixfmt_gray.h b/src/agg/agg_pixfmt_gray.h
index 8f3f4ec9d..d03dc8650 100644
--- a/src/agg/agg_pixfmt_gray.h
+++ b/src/agg/agg_pixfmt_gray.h
@@ -1,25 +1,16 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
 //
 // Adaptation for high precision colors has been sponsored by 
@@ -34,8 +25,7 @@
 #define AGG_PIXFMT_GRAY_INCLUDED
 
 #include <string.h>
-#include "agg_basics.h"
-#include "agg_color_gray.h"
+#include "agg_pixfmt_base.h"
 #include "agg_rendering_buffer.h"
 
 namespace agg
@@ -47,12 +37,22 @@ namespace agg
         typedef ColorT color_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum base_scale_e { base_shift = color_type::base_shift };
+        typedef typename color_type::long_type long_type;
 
-        static AGG_INLINE void blend_pix(value_type* p, unsigned cv, 
-                                         unsigned alpha, unsigned cover=0)
+        // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
+        // compositing function. Since the render buffer is opaque we skip the
+        // initial premultiply and final demultiply.
+
+        static AGG_INLINE void blend_pix(value_type* p, 
+            value_type cv, value_type alpha, cover_type cover)
         {
-            *p = (value_type)((((cv - calc_type(*p)) * alpha) + (calc_type(*p) << base_shift)) >> base_shift);
+            blend_pix(p, cv, color_type::mult_cover(alpha, cover));
+        }
+
+        static AGG_INLINE void blend_pix(value_type* p, 
+            value_type cv, value_type alpha)
+        {
+            *p = color_type::lerp(*p, cv, alpha);
         }
     };
 
@@ -63,20 +63,21 @@ namespace agg
         typedef ColorT color_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum base_scale_e { base_shift = color_type::base_shift };
+        typedef typename color_type::long_type long_type;
 
-        static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
-                                         unsigned alpha, unsigned cover)
+        // Blend pixels using the premultiplied form of Alvy-Ray Smith's
+        // compositing function. 
+
+        static AGG_INLINE void blend_pix(value_type* p, 
+            value_type cv, value_type alpha, cover_type cover)
         {
-            alpha = color_type::base_mask - alpha;
-            cover = (cover + 1) << (base_shift - 8);
-            *p = (value_type)((*p * alpha + cv * cover) >> base_shift);
+            blend_pix(p, color_type::mult_cover(cv, cover), color_type::mult_cover(alpha, cover));
         }
 
-        static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
-                                         unsigned alpha)
+        static AGG_INLINE void blend_pix(value_type* p, 
+            value_type cv, value_type alpha)
         {
-            *p = (value_type)(((*p * (color_type::base_mask - alpha)) >> base_shift) + cv);
+            *p = color_type::prelerp(*p, cv, alpha);
         }
     };
     
@@ -121,10 +122,11 @@ namespace agg
 
 
     //=================================================pixfmt_alpha_blend_gray
-    template<class Blender, class RenBuf, unsigned Step=1, unsigned Offset=0>
+    template<class Blender, class RenBuf, unsigned Step = 1, unsigned Offset = 0>
     class pixfmt_alpha_blend_gray
     {
     public:
+        typedef pixfmt_gray_tag pixfmt_category;
         typedef RenBuf   rbuf_type;
         typedef typename rbuf_type::row_data row_data;
         typedef Blender  blender_type;
@@ -132,54 +134,117 @@ namespace agg
         typedef int                               order_type; // A fake one
         typedef typename color_type::value_type   value_type;
         typedef typename color_type::calc_type    calc_type;
-        enum base_scale_e 
+        enum 
         {
-            base_shift = color_type::base_shift,
-            base_scale = color_type::base_scale,
-            base_mask  = color_type::base_mask,
-            pix_width  = sizeof(value_type),
-            pix_step   = Step,
-            pix_offset = Offset
+            num_components = 1,
+            pix_width = sizeof(value_type) * Step,
+            pix_step = Step,
+            pix_offset = Offset,
+        };
+        struct pixel_type
+        {
+            value_type c[num_components];
+
+            void set(value_type v)
+            {
+                c[0] = v;
+            }
+
+            void set(const color_type& color)
+            {
+                set(color.v);
+            }
+
+            void get(value_type& v) const
+            {
+                v = c[0];
+            }
+
+            color_type get() const
+            {
+                return color_type(c[0]);
+            }
+
+            pixel_type* next()
+            {
+                return (pixel_type*)(c + pix_step);
+            }
+
+            const pixel_type* next() const
+            {
+                return (const pixel_type*)(c + pix_step);
+            }
+
+            pixel_type* advance(int n)
+            {
+                return (pixel_type*)(c + n * pix_step);
+            }
+
+            const pixel_type* advance(int n) const
+            {
+                return (const pixel_type*)(c + n * pix_step);
+            }
         };
 
     private:
         //--------------------------------------------------------------------
-        static AGG_INLINE void copy_or_blend_pix(value_type* p, 
-                                                 const color_type& c, 
-                                                 unsigned cover)
+        AGG_INLINE void blend_pix(pixel_type* p, 
+            value_type v, value_type a, 
+            unsigned cover)
         {
-            if (c.a)
+            blender_type::blend_pix(p->c, v, a, cover);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE void blend_pix(pixel_type* p, value_type v, value_type a)
+        {
+            blender_type::blend_pix(p->c, v, a);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover)
+        {
+            blender_type::blend_pix(p->c, c.v, c.a, cover);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE void blend_pix(pixel_type* p, const color_type& c)
+        {
+            blender_type::blend_pix(p->c, c.v, c.a);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
+        {
+            if (!c.is_transparent())
             {
-                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
-                if(alpha == base_mask)
+                if (c.is_opaque() && cover == cover_mask)
                 {
-                    *p = c.v;
+                    p->set(c);
                 }
                 else
                 {
-                    Blender::blend_pix(p, c.v, alpha, cover);
+                    blend_pix(p, c, cover);
                 }
             }
         }
 
-
-        static AGG_INLINE void copy_or_blend_pix(value_type* p, 
-                                                 const color_type& c)
+        //--------------------------------------------------------------------
+        AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
-                if(c.a == base_mask)
+                if (c.is_opaque())
                 {
-                    *p = c.v;
+                    p->set(c);
                 }
                 else
                 {
-                    Blender::blend_pix(p, c.v, c.a);
+                    blend_pix(p, c);
                 }
             }
         }
 
-
     public:
         //--------------------------------------------------------------------
         explicit pixfmt_alpha_blend_gray(rbuf_type& rb) :
@@ -192,7 +257,7 @@ namespace agg
         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)))
+            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), 
@@ -210,61 +275,98 @@ namespace agg
         AGG_INLINE int      stride() const { return m_rbuf->stride(); }
 
         //--------------------------------------------------------------------
-              int8u* row_ptr(int y)       { 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 * Step + Offset;
+        //--------------------------------------------------------------------
+        AGG_INLINE int8u* pix_ptr(int x, int y) 
+        { 
+            return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
         }
 
-        int8u* pix_ptr(int x, int y)
+        AGG_INLINE const int8u* pix_ptr(int x, int y) const 
+        { 
+            return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
+        }
+
+        // Return pointer to pixel value, forcing row to be allocated.
+        AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) 
         {
-            return m_rbuf->row_ptr(y) + x * Step + Offset;
+            return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset));
+        }
+
+        // Return pointer to pixel value, or null if row not allocated.
+        AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const 
+        {
+            int8u* p = m_rbuf->row_ptr(y);
+            return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0;
+        }
+
+        // Get pixel pointer from raw buffer pointer.
+        AGG_INLINE static pixel_type* pix_value_ptr(void* p) 
+        {
+            return (pixel_type*)((value_type*)p + pix_offset);
+        }
+
+        // Get pixel pointer from raw buffer pointer.
+        AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) 
+        {
+            return (const pixel_type*)((const value_type*)p + pix_offset);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE static void write_plain_color(void* p, color_type c)
+        {
+            // Grayscale formats are implicitly premultiplied.
+            c.premultiply();
+            pix_value_ptr(p)->set(c);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE static color_type read_plain_color(const void* p)
+        {
+            return pix_value_ptr(p)->get();
         }
 
         //--------------------------------------------------------------------
         AGG_INLINE static void make_pix(int8u* p, const color_type& c)
         {
-            *(value_type*)p = c.v;
+            ((pixel_type*)p)->set(c);
         }
 
         //--------------------------------------------------------------------
         AGG_INLINE color_type pixel(int x, int y) const
         {
-            value_type* p = (value_type*)m_rbuf->row_ptr(y) + x * Step + Offset;
-            return color_type(*p);
+            if (const pixel_type* p = pix_value_ptr(x, y))
+            {
+                return p->get();
+            }
+            return color_type::no_color();
         }
 
         //--------------------------------------------------------------------
         AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
         {
-            *((value_type*)m_rbuf->row_ptr(x, y, 1) + x * Step + Offset) = c.v;
+            pix_value_ptr(x, y, 1)->set(c);
         }
 
         //--------------------------------------------------------------------
         AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
         {
-            copy_or_blend_pix((value_type*)
-                               m_rbuf->row_ptr(x, y, 1) + x * Step + Offset, 
-                               c, 
-                               cover);
+            copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
         }
 
-
         //--------------------------------------------------------------------
         AGG_INLINE void copy_hline(int x, int y, 
                                    unsigned len, 
                                    const color_type& c)
         {
-            value_type* p = (value_type*)
-                m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
-
+            pixel_type* p = pix_value_ptr(x, y, len);
             do
             {
-                *p = c.v; 
-                p += Step;
+                p->set(c);
+                p = p->next();
             }
             while(--len);
         }
@@ -277,12 +379,9 @@ namespace agg
         {
             do
             {
-                value_type* p = (value_type*)
-                    m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
-
-                *p = c.v;
+                pix_value_ptr(x, y++, 1)->set(c);
             }
-            while(--len);
+            while (--len);
         }
 
 
@@ -292,29 +391,27 @@ namespace agg
                          const color_type& c,
                          int8u cover)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
-                value_type* p = (value_type*)
-                    m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+                pixel_type* p = pix_value_ptr(x, y, len);
 
-                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
-                if(alpha == base_mask)
+                if (c.is_opaque() && cover == cover_mask)
                 {
                     do
                     {
-                        *p = c.v; 
-                        p += Step;
+                        p->set(c);
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
                 else
                 {
                     do
                     {
-                        Blender::blend_pix(p, c.v, alpha, cover);
-                        p += Step;
+                        blend_pix(p, c, cover);
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
@@ -326,31 +423,23 @@ namespace agg
                          const color_type& c,
                          int8u cover)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
-                value_type* p;
-                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
-                if(alpha == base_mask)
+                if (c.is_opaque() && cover == cover_mask)
                 {
                     do
                     {
-                        p = (value_type*)
-                            m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
-
-                        *p = c.v; 
+                        pix_value_ptr(x, y++, 1)->set(c);
                     }
-                    while(--len);
+                    while (--len);
                 }
                 else
                 {
                     do
                     {
-                        p = (value_type*)
-                            m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
-
-                        Blender::blend_pix(p, c.v, alpha, cover);
+                        blend_pix(pix_value_ptr(x, y++, 1), c, cover);
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
@@ -362,26 +451,24 @@ namespace agg
                                const color_type& c,
                                const int8u* covers)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
-                value_type* p = (value_type*)
-                    m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+                pixel_type* p = pix_value_ptr(x, y, len);
 
                 do 
                 {
-                    calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
-                    if(alpha == base_mask)
+                    if (c.is_opaque() && *covers == cover_mask)
                     {
-                        *p = c.v;
+                        p->set(c);
                     }
                     else
                     {
-                        Blender::blend_pix(p, c.v, alpha, *covers);
+                        blend_pix(p, c, *covers);
                     }
-                    p += Step;
+                    p = p->next();
                     ++covers;
                 }
-                while(--len);
+                while (--len);
             }
         }
 
@@ -392,26 +479,23 @@ namespace agg
                                const color_type& c,
                                const int8u* covers)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
                 do 
                 {
-                    calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
+                    pixel_type* p = pix_value_ptr(x, y++, 1);
 
-                    value_type* p = (value_type*)
-                        m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
-
-                    if(alpha == base_mask)
+                    if (c.is_opaque() && *covers == cover_mask)
                     {
-                        *p = c.v;
+                        p->set(c);
                     }
                     else
                     {
-                        Blender::blend_pix(p, c.v, alpha, *covers);
+                        blend_pix(p, c, *covers);
                     }
                     ++covers;
                 }
-                while(--len);
+                while (--len);
             }
         }
 
@@ -421,16 +505,14 @@ namespace agg
                               unsigned len, 
                               const color_type* colors)
         {
-            value_type* p = (value_type*)
-                m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+            pixel_type* p = pix_value_ptr(x, y, len);
 
             do 
             {
-                *p = colors->v;
-                p += Step;
-                ++colors;
+                p->set(*colors++);
+                p = p->next();
             }
-            while(--len);
+            while (--len);
         }
 
 
@@ -441,12 +523,9 @@ namespace agg
         {
             do 
             {
-                value_type* p = (value_type*)
-                    m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
-                *p = colors->v;
-                ++colors;
+                pix_value_ptr(x, y++, 1)->set(*colors++);
             }
-            while(--len);
+            while (--len);
         }
 
 
@@ -457,50 +536,40 @@ namespace agg
                                const int8u* covers,
                                int8u cover)
         {
-            value_type* p = (value_type*)
-                m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+            pixel_type* p = pix_value_ptr(x, y, len);
 
-            if(covers)
+            if (covers)
             {
                 do 
                 {
                     copy_or_blend_pix(p, *colors++, *covers++);
-                    p += Step;
+                    p = p->next();
                 }
-                while(--len);
+                while (--len);
             }
             else
             {
-                if(cover == 255)
+                if (cover == cover_mask)
                 {
                     do 
                     {
-                        if(colors->a == base_mask)
-                        {
-                            *p = colors->v;
-                        }
-                        else
-                        {
-                            copy_or_blend_pix(p, *colors);
-                        }
-                        p += Step;
-                        ++colors;
+                        copy_or_blend_pix(p, *colors++);
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
                 else
                 {
                     do 
                     {
                         copy_or_blend_pix(p, *colors++, cover);
-                        p += Step;
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
-
-
+        
 
         //--------------------------------------------------------------------
         void blend_color_vspan(int x, int y,
@@ -509,49 +578,31 @@ namespace agg
                                const int8u* covers,
                                int8u cover)
         {
-            value_type* p;
-            if(covers)
+            if (covers)
             {
                 do 
                 {
-                    p = (value_type*)
-                        m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
-
-                    copy_or_blend_pix(p, *colors++, *covers++);
+                    copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
                 }
-                while(--len);
+                while (--len);
             }
             else
             {
-                if(cover == 255)
+                if (cover == cover_mask)
                 {
                     do 
                     {
-                        p = (value_type*)
-                            m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
-
-                        if(colors->a == base_mask)
-                        {
-                            *p = colors->v;
-                        }
-                        else
-                        {
-                            copy_or_blend_pix(p, *colors);
-                        }
-                        ++colors;
+                        copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
                     }
-                    while(--len);
+                    while (--len);
                 }
                 else
                 {
                     do 
                     {
-                        p = (value_type*)
-                            m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
-
-                        copy_or_blend_pix(p, *colors++, cover);
+                        copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
@@ -560,22 +611,19 @@ namespace agg
         template<class Function> void for_each_pixel(Function f)
         {
             unsigned y;
-            for(y = 0; y < height(); ++y)
+            for (y = 0; y < height(); ++y)
             {
                 row_data r = m_rbuf->row(y);
-                if(r.ptr)
+                if (r.ptr)
                 {
                     unsigned len = r.x2 - r.x1 + 1;
-
-                    value_type* p = (value_type*)
-                        m_rbuf->row_ptr(r.x1, y, len) + r.x1 * Step + Offset;
-
+                    pixel_type* p = pix_value_ptr(r.x1, y, len);
                     do
                     {
-                        f(p);
-                        p += Step;
+                        f(p->c);
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
@@ -599,8 +647,7 @@ namespace agg
                        int xsrc, int ysrc,
                        unsigned len)
         {
-            const int8u* p = from.row_ptr(ysrc);
-            if(p)
+            if (const int8u* p = from.row_ptr(ysrc))
             {
                 memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, 
                         p + xsrc * pix_width, 
@@ -609,6 +656,7 @@ namespace agg
         }
 
         //--------------------------------------------------------------------
+        // Blend from single color, using grayscale surface as alpha channel.
         template<class SrcPixelFormatRenderer>
         void blend_from_color(const SrcPixelFormatRenderer& from, 
                               const color_type& color,
@@ -617,25 +665,26 @@ namespace agg
                               unsigned len,
                               int8u cover)
         {
-            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
-            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
-            if(psrc)
+            typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
+            typedef typename SrcPixelFormatRenderer::color_type src_color_type;
+
+            if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
             {
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
+                pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
+
                 do 
                 {
-                    copy_or_blend_pix(pdst, 
-                                      color, 
-                                      (*psrc * cover + base_mask) >> base_shift);
-                    ++psrc;
-                    ++pdst;
+                    copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0]));
+                    psrc = psrc->next();
+                    pdst = pdst->next();
                 }
-                while(--len);
+                while (--len);
             }
         }
 
         //--------------------------------------------------------------------
+        // Blend from color table, using grayscale surface as indexes into table.
+        // Obviously, this only works for integer value types.
         template<class SrcPixelFormatRenderer>
         void blend_from_lut(const SrcPixelFormatRenderer& from, 
                             const color_type* color_lut,
@@ -644,19 +693,19 @@ namespace agg
                             unsigned len,
                             int8u cover)
         {
-            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
-            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
-            if(psrc)
+            typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
+
+            if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
             {
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
+                pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
+
                 do 
                 {
-                    copy_or_blend_pix(pdst, color_lut[*psrc], cover);
-                    ++psrc;
-                    ++pdst;
+                    copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
+                    psrc = psrc->next();
+                    pdst = pdst->next();
                 }
-                while(--len);
+                while (--len);
             }
         }
 
@@ -664,15 +713,25 @@ namespace agg
         rbuf_type* m_rbuf;
     };
 
-    typedef blender_gray<gray8>      blender_gray8;
-    typedef blender_gray_pre<gray8>  blender_gray8_pre;
-    typedef blender_gray<gray16>     blender_gray16;
-    typedef blender_gray_pre<gray16> blender_gray16_pre;
+    typedef blender_gray<gray8> blender_gray8;
+    typedef blender_gray<sgray8> blender_sgray8;
+    typedef blender_gray<gray16> blender_gray16;
+    typedef blender_gray<gray32> blender_gray32;
 
-    typedef pixfmt_alpha_blend_gray<blender_gray8,      rendering_buffer> pixfmt_gray8;      //----pixfmt_gray8
-    typedef pixfmt_alpha_blend_gray<blender_gray8_pre,  rendering_buffer> pixfmt_gray8_pre;  //----pixfmt_gray8_pre
-    typedef pixfmt_alpha_blend_gray<blender_gray16,     rendering_buffer> pixfmt_gray16;     //----pixfmt_gray16
-    typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre; //----pixfmt_gray16_pre
+    typedef blender_gray_pre<gray8> blender_gray8_pre;
+    typedef blender_gray_pre<sgray8> blender_sgray8_pre;
+    typedef blender_gray_pre<gray16> blender_gray16_pre;
+    typedef blender_gray_pre<gray32> blender_gray32_pre;
+
+    typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8;
+    typedef pixfmt_alpha_blend_gray<blender_sgray8, rendering_buffer> pixfmt_sgray8;
+    typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16;
+    typedef pixfmt_alpha_blend_gray<blender_gray32, rendering_buffer> pixfmt_gray32;
+
+    typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre;
+    typedef pixfmt_alpha_blend_gray<blender_sgray8_pre, rendering_buffer> pixfmt_sgray8_pre;
+    typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre;
+    typedef pixfmt_alpha_blend_gray<blender_gray32_pre, rendering_buffer> pixfmt_gray32_pre;
 }
 
 #endif
diff --git a/src/agg/agg_pixfmt_rgb.h b/src/agg/agg_pixfmt_rgb.h
index 48947178b..6fa8772ce 100644
--- a/src/agg/agg_pixfmt_rgb.h
+++ b/src/agg/agg_pixfmt_rgb.h
@@ -1,25 +1,16 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
 //
 // Adaptation for high precision colors has been sponsored by 
@@ -34,8 +25,7 @@
 #define AGG_PIXFMT_RGB_INCLUDED
 
 #include <string.h>
-#include "agg_basics.h"
-#include "agg_color_rgba.h"
+#include "agg_pixfmt_base.h"
 #include "agg_rendering_buffer.h"
 
 namespace agg
@@ -83,66 +73,73 @@ namespace agg
 
 
     //=========================================================blender_rgb
-    template<class ColorT, class Order> struct blender_rgb
+    template<class ColorT, class Order> 
+    struct blender_rgb
     {
         typedef ColorT color_type;
         typedef Order order_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum base_scale_e { base_shift = color_type::base_shift };
+        typedef typename color_type::long_type long_type;
+
+        // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
+        // compositing function. Since the render buffer is opaque we skip the
+        // initial premultiply and final demultiply.
 
         //--------------------------------------------------------------------
         static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb, 
-                                         unsigned alpha, 
-                                         unsigned cover=0)
+            value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
         {
-            p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >> base_shift);
-            p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha) >> base_shift);
-            p[Order::B] += (value_type)(((cb - p[Order::B]) * alpha) >> base_shift);
+            blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
+        }
+        
+        //--------------------------------------------------------------------
+        static AGG_INLINE void blend_pix(value_type* p, 
+            value_type cr, value_type cg, value_type cb, value_type alpha)
+        {
+            p[Order::R] = color_type::lerp(p[Order::R], cr, alpha);
+            p[Order::G] = color_type::lerp(p[Order::G], cg, alpha);
+            p[Order::B] = color_type::lerp(p[Order::B], cb, alpha);
         }
     };
 
-
     //======================================================blender_rgb_pre
-    template<class ColorT, class Order> struct blender_rgb_pre
+    template<class ColorT, class Order> 
+    struct blender_rgb_pre
     {
         typedef ColorT color_type;
         typedef Order order_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum base_scale_e { base_shift = color_type::base_shift };
+        typedef typename color_type::long_type long_type;
+
+        // Blend pixels using the premultiplied form of Alvy-Ray Smith's
+        // compositing function. 
 
         //--------------------------------------------------------------------
         static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned alpha,
-                                         unsigned cover)
+            value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
         {
-            alpha = color_type::base_mask - alpha;
-            cover = (cover + 1) << (base_shift - 8);
-            p[Order::R] = (value_type)((p[Order::R] * alpha + cr * cover) >> base_shift);
-            p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift);
-            p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift);
+            blend_pix(p, 
+                color_type::mult_cover(cr, cover), 
+                color_type::mult_cover(cg, cover), 
+                color_type::mult_cover(cb, cover), 
+                color_type::mult_cover(alpha, cover));
         }
 
         //--------------------------------------------------------------------
         static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned alpha)
+            value_type cr, value_type cg, value_type cb, value_type alpha)
         {
-            alpha = color_type::base_mask - alpha;
-            p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr);
-            p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg);
-            p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb);
+            p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha);
+            p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha);
+            p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha);
         }
-
     };
 
-
-
     //===================================================blender_rgb_gamma
-    template<class ColorT, class Order, class Gamma> class blender_rgb_gamma
+    template<class ColorT, class Order, class Gamma> 
+    class blender_rgb_gamma : public blender_base<ColorT, Order>
     {
     public:
         typedef ColorT color_type;
@@ -150,7 +147,7 @@ namespace agg
         typedef Gamma gamma_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum base_scale_e { base_shift = color_type::base_shift };
+        typedef typename color_type::long_type long_type;
 
         //--------------------------------------------------------------------
         blender_rgb_gamma() : m_gamma(0) {}
@@ -158,29 +155,34 @@ namespace agg
 
         //--------------------------------------------------------------------
         AGG_INLINE void blend_pix(value_type* p, 
-                                  unsigned cr, unsigned cg, unsigned cb,
-                                  unsigned alpha, 
-                                  unsigned cover=0)
+            value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
+        {
+            blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
+        }
+        
+        //--------------------------------------------------------------------
+        AGG_INLINE void blend_pix(value_type* p, 
+            value_type cr, value_type cg, value_type cb, value_type alpha)
         {
             calc_type r = m_gamma->dir(p[Order::R]);
             calc_type g = m_gamma->dir(p[Order::G]);
             calc_type b = m_gamma->dir(p[Order::B]);
-            p[Order::R] = m_gamma->inv((((m_gamma->dir(cr) - r) * alpha) >> base_shift) + r);
-            p[Order::G] = m_gamma->inv((((m_gamma->dir(cg) - g) * alpha) >> base_shift) + g);
-            p[Order::B] = m_gamma->inv((((m_gamma->dir(cb) - b) * alpha) >> base_shift) + b);
+            p[Order::R] = m_gamma->inv(color_type::downscale((m_gamma->dir(cr) - r) * alpha) + r);
+            p[Order::G] = m_gamma->inv(color_type::downscale((m_gamma->dir(cg) - g) * alpha) + g);
+            p[Order::B] = m_gamma->inv(color_type::downscale((m_gamma->dir(cb) - b) * alpha) + b);
         }
-
+        
     private:
         const gamma_type* m_gamma;
     };
 
 
-
-    
     //==================================================pixfmt_alpha_blend_rgb
-    template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb
+    template<class Blender, class RenBuf, unsigned Step, unsigned Offset = 0> 
+    class pixfmt_alpha_blend_rgb
     {
     public:
+        typedef pixfmt_rgb_tag pixfmt_category;
         typedef RenBuf   rbuf_type;
         typedef Blender  blender_type;
         typedef typename rbuf_type::row_data row_data;
@@ -188,56 +190,125 @@ namespace agg
         typedef typename blender_type::order_type order_type;
         typedef typename color_type::value_type value_type;
         typedef typename color_type::calc_type calc_type;
-        enum base_scale_e 
+        enum 
         {
-            base_shift = color_type::base_shift,
-            base_scale = color_type::base_scale,
-            base_mask  = color_type::base_mask,
-            pix_width  = sizeof(value_type) * 3
+            num_components = 3,
+            pix_step = Step,
+            pix_offset = Offset,
+            pix_width = sizeof(value_type) * pix_step
+        };
+        struct pixel_type
+        {
+            value_type c[num_components];
+
+            void set(value_type r, value_type g, value_type b)
+            {
+                c[order_type::R] = r;
+                c[order_type::G] = g;
+                c[order_type::B] = b;
+            }
+
+            void set(const color_type& color)
+            {
+                set(color.r, color.g, color.b);
+            }
+
+            void get(value_type& r, value_type& g, value_type& b) const
+            {
+                r = c[order_type::R];
+                g = c[order_type::G];
+                b = c[order_type::B];
+            }
+
+            color_type get() const
+            {
+                return color_type(
+                    c[order_type::R], 
+                    c[order_type::G], 
+                    c[order_type::B]);
+            }
+
+            pixel_type* next()
+            {
+                return (pixel_type*)(c + pix_step);
+            }
+
+            const pixel_type* next() const
+            {
+                return (const pixel_type*)(c + pix_step);
+            }
+
+            pixel_type* advance(int n)
+            {
+                return (pixel_type*)(c + n * pix_step);
+            }
+
+            const pixel_type* advance(int n) const
+            {
+                return (const pixel_type*)(c + n * pix_step);
+            }
         };
 
     private:
         //--------------------------------------------------------------------
-        AGG_INLINE void copy_or_blend_pix(value_type* p, 
-                                          const color_type& c, 
-                                          unsigned cover)
+        AGG_INLINE void blend_pix(pixel_type* p, 
+            value_type r, value_type g, value_type b, value_type a, 
+            unsigned cover)
         {
-            if (c.a)
+            m_blender.blend_pix(p->c, r, g, b, a, cover);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE void blend_pix(pixel_type* p, 
+            value_type r, value_type g, value_type b, value_type a)
+        {
+            m_blender.blend_pix(p->c, r, g, b, a);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover)
+        {
+            m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE void blend_pix(pixel_type* p, const color_type& c)
+        {
+            m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
+        {
+            if (!c.is_transparent())
             {
-                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
-                if(alpha == base_mask)
+                if (c.is_opaque() && cover == cover_mask)
                 {
-                    p[order_type::R] = c.r;
-                    p[order_type::G] = c.g;
-                    p[order_type::B] = c.b;
+                    p->set(c);
                 }
                 else
                 {
-                    m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
+                    blend_pix(p, c, cover);
                 }
             }
         }
 
         //--------------------------------------------------------------------
-        AGG_INLINE void copy_or_blend_pix(value_type* p, 
-                                          const color_type& c)
+        AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
-                if(c.a == base_mask)
+                if (c.is_opaque())
                 {
-                    p[order_type::R] = c.r;
-                    p[order_type::G] = c.g;
-                    p[order_type::B] = c.b;
+                    p->set(c);
                 }
                 else
                 {
-                    m_blender.blend_pix(p, c.r, c.g, c.b, c.a);
+                    blend_pix(p, c);
                 }
             }
         }
 
-
     public:
         //--------------------------------------------------------------------
         explicit pixfmt_alpha_blend_rgb(rbuf_type& rb) :
@@ -250,7 +321,7 @@ namespace agg
         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)))
+            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), 
@@ -278,59 +349,91 @@ namespace agg
         //--------------------------------------------------------------------
         AGG_INLINE int8u* pix_ptr(int x, int y) 
         { 
-            return m_rbuf->row_ptr(y) + x * pix_width; 
+            return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
         }
 
         AGG_INLINE const int8u* pix_ptr(int x, int y) const 
         { 
-            return m_rbuf->row_ptr(y) + x * pix_width; 
+            return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
+        }
+
+        // Return pointer to pixel value, forcing row to be allocated.
+        AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) 
+        {
+            return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset));
+        }
+
+        // Return pointer to pixel value, or null if row not allocated.
+        AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const 
+        {
+            int8u* p = m_rbuf->row_ptr(y);
+            return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0;
+        }
+
+        // Get pixel pointer from raw buffer pointer.
+        AGG_INLINE static pixel_type* pix_value_ptr(void* p) 
+        {
+            return (pixel_type*)((value_type*)p + pix_offset);
+        }
+
+        // Get pixel pointer from raw buffer pointer.
+        AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) 
+        {
+            return (const pixel_type*)((const value_type*)p + pix_offset);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE static void write_plain_color(void* p, color_type c)
+        {
+            // RGB formats are implicitly premultiplied.
+            c.premultiply();
+            pix_value_ptr(p)->set(c);
+        }
+
+        //--------------------------------------------------------------------
+        AGG_INLINE static color_type read_plain_color(const void* p)
+        {
+            return pix_value_ptr(p)->get();
         }
 
         //--------------------------------------------------------------------
         AGG_INLINE static void make_pix(int8u* p, const color_type& c)
         {
-            ((value_type*)p)[order_type::R] = c.r;
-            ((value_type*)p)[order_type::G] = c.g;
-            ((value_type*)p)[order_type::B] = c.b;
+            ((pixel_type*)p)->set(c);
         }
 
         //--------------------------------------------------------------------
         AGG_INLINE color_type pixel(int x, int y) const
         {
-            value_type* p = (value_type*)m_rbuf->row_ptr(y) + x + x + x;
-            return color_type(p[order_type::R], 
-                              p[order_type::G], 
-                              p[order_type::B]);
+            if (const pixel_type* p = pix_value_ptr(x, y))
+            {
+                return p->get();
+            }
+            return color_type::no_color();
         }
 
         //--------------------------------------------------------------------
         AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
         {
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x;
-            p[order_type::R] = c.r;
-            p[order_type::G] = c.g;
-            p[order_type::B] = c.b;
+            pix_value_ptr(x, y, 1)->set(c);
         }
 
         //--------------------------------------------------------------------
         AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
         {
-            copy_or_blend_pix((value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x, c, cover);
+            copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
         }
 
-
         //--------------------------------------------------------------------
         AGG_INLINE void copy_hline(int x, int y, 
                                    unsigned len, 
                                    const color_type& c)
         {
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + x + x + x;
+            pixel_type* p = pix_value_ptr(x, y, len);
             do
             {
-                p[order_type::R] = c.r; 
-                p[order_type::G] = c.g; 
-                p[order_type::B] = c.b;
-                p += 3;
+                p->set(c);
+                p = p->next();
             }
             while(--len);
         }
@@ -343,47 +446,38 @@ namespace agg
         {
             do
             {
-                value_type* p = (value_type*)
-                    m_rbuf->row_ptr(x, y++, 1) + x + x + x;
-                p[order_type::R] = c.r; 
-                p[order_type::G] = c.g; 
-                p[order_type::B] = c.b;
+                pix_value_ptr(x, y++, 1)->set(c);
             }
-            while(--len);
+            while (--len);
         }
 
-
         //--------------------------------------------------------------------
         void blend_hline(int x, int y,
                          unsigned len, 
                          const color_type& c,
                          int8u cover)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
-                value_type* p = (value_type*)
-                    m_rbuf->row_ptr(x, y, len) + x + x + x;
+                pixel_type* p = pix_value_ptr(x, y, len);
 
-                calc_type alpha = (calc_type(c.a) * (calc_type(cover) + 1)) >> 8;
-                if(alpha == base_mask)
+                if (c.is_opaque() && cover == cover_mask)
                 {
                     do
                     {
-                        p[order_type::R] = c.r; 
-                        p[order_type::G] = c.g; 
-                        p[order_type::B] = c.b;
-                        p += 3;
+                        p->set(c);
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
                 else
                 {
                     do
                     {
-                        m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
-                        p += 3;
+                        blend_pix(p, c, cover);
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
@@ -395,66 +489,51 @@ namespace agg
                          const color_type& c,
                          int8u cover)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
-                value_type* p;
-                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
-                if(alpha == base_mask)
+                if (c.is_opaque() && cover == cover_mask)
                 {
                     do
                     {
-                        p = (value_type*)
-                            m_rbuf->row_ptr(x, y++, 1) + x + x + x;
-
-                        p[order_type::R] = c.r; 
-                        p[order_type::G] = c.g; 
-                        p[order_type::B] = c.b;
+                        pix_value_ptr(x, y++, 1)->set(c);
                     }
-                    while(--len);
+                    while (--len);
                 }
                 else
                 {
                     do
                     {
-                        p = (value_type*)
-                            m_rbuf->row_ptr(x, y++, 1) + x + x + x;
-
-                        m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
+                        blend_pix(pix_value_ptr(x, y++, 1), c, cover);
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
 
-
         //--------------------------------------------------------------------
         void blend_solid_hspan(int x, int y,
                                unsigned len, 
                                const color_type& c,
                                const int8u* covers)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
-                value_type* p = (value_type*)
-                    m_rbuf->row_ptr(x, y, len) + x + x + x;
+                pixel_type* p = pix_value_ptr(x, y, len);
 
                 do 
                 {
-                    calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
-                    if(alpha == base_mask)
+                    if (c.is_opaque() && *covers == cover_mask)
                     {
-                        p[order_type::R] = c.r;
-                        p[order_type::G] = c.g;
-                        p[order_type::B] = c.b;
+                        p->set(c);
                     }
                     else
                     {
-                        m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers);
+                        blend_pix(p, c, *covers);
                     }
-                    p += 3;
+                    p = p->next();
                     ++covers;
                 }
-                while(--len);
+                while (--len);
             }
         }
 
@@ -465,48 +544,39 @@ namespace agg
                                const color_type& c,
                                const int8u* covers)
         {
-            if (c.a)
+            if (!c.is_transparent())
             {
                 do 
                 {
-                    value_type* p = (value_type*)
-                        m_rbuf->row_ptr(x, y++, 1) + x + x + x;
+                    pixel_type* p = pix_value_ptr(x, y++, 1);
 
-                    calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
-                    if(alpha == base_mask)
+                    if (c.is_opaque() && *covers == cover_mask)
                     {
-                        p[order_type::R] = c.r;
-                        p[order_type::G] = c.g;
-                        p[order_type::B] = c.b;
+                        p->set(c);
                     }
                     else
                     {
-                        m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers);
+                        blend_pix(p, c, *covers);
                     }
                     ++covers;
                 }
-                while(--len);
+                while (--len);
             }
         }
 
-
         //--------------------------------------------------------------------
         void copy_color_hspan(int x, int y,
                               unsigned len, 
                               const color_type* colors)
         {
-            value_type* p = (value_type*)
-                m_rbuf->row_ptr(x, y, len) + x + x + x;
+            pixel_type* p = pix_value_ptr(x, y, len);
 
             do 
             {
-                p[order_type::R] = colors->r;
-                p[order_type::G] = colors->g;
-                p[order_type::B] = colors->b;
-                ++colors;
-                p += 3;
+                p->set(*colors++);
+                p = p->next();
             }
-            while(--len);
+            while (--len);
         }
 
 
@@ -517,17 +587,11 @@ namespace agg
         {
             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;
+                pix_value_ptr(x, y++, 1)->set(*colors++);
             }
-            while(--len);
+            while (--len);
         }
 
-
         //--------------------------------------------------------------------
         void blend_color_hspan(int x, int y,
                                unsigned len, 
@@ -535,43 +599,40 @@ namespace agg
                                const int8u* covers,
                                int8u cover)
         {
-            value_type* p = (value_type*)
-                m_rbuf->row_ptr(x, y, len) + x + x + x;
+            pixel_type* p = pix_value_ptr(x, y, len);
 
-            if(covers)
+            if (covers)
             {
                 do 
                 {
                     copy_or_blend_pix(p, *colors++, *covers++);
-                    p += 3;
+                    p = p->next();
                 }
-                while(--len);
+                while (--len);
             }
             else
             {
-                if(cover == 255)
+                if (cover == cover_mask)
                 {
                     do 
                     {
                         copy_or_blend_pix(p, *colors++);
-                        p += 3;
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
                 else
                 {
                     do 
                     {
                         copy_or_blend_pix(p, *colors++, cover);
-                        p += 3;
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
 
-
-
         //--------------------------------------------------------------------
         void blend_color_vspan(int x, int y,
                                unsigned len, 
@@ -579,41 +640,31 @@ namespace agg
                                const int8u* covers,
                                int8u cover)
         {
-            value_type* p;
-            if(covers)
+            if (covers)
             {
                 do 
                 {
-                    p = (value_type*)
-                        m_rbuf->row_ptr(x, y++, 1) + x + x + x;
-
-                    copy_or_blend_pix(p, *colors++, *covers++);
+                    copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
                 }
-                while(--len);
+                while (--len);
             }
             else
             {
-                if(cover == 255)
+                if (cover == cover_mask)
                 {
                     do 
                     {
-                        p = (value_type*)
-                            m_rbuf->row_ptr(x, y++, 1) + x + x + x;
-
-                        copy_or_blend_pix(p, *colors++);
+                        copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
                     }
-                    while(--len);
+                    while (--len);
                 }
                 else
                 {
                     do 
                     {
-                        p = (value_type*)
-                            m_rbuf->row_ptr(x, y++, 1) + x + x + x;
-
-                        copy_or_blend_pix(p, *colors++, cover);
+                        copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
@@ -621,21 +672,19 @@ namespace agg
         //--------------------------------------------------------------------
         template<class Function> void for_each_pixel(Function f)
         {
-            unsigned y;
-            for(y = 0; y < height(); ++y)
+            for (unsigned y = 0; y < height(); ++y)
             {
                 row_data r = m_rbuf->row(y);
-                if(r.ptr)
+                if (r.ptr)
                 {
                     unsigned len = r.x2 - r.x1 + 1;
-                    value_type* p = (value_type*)
-                        m_rbuf->row_ptr(r.x1, y, len) + r.x1 * 3;
+                    pixel_type* p = pix_value_ptr(r.x1, y, len);
                     do
                     {
-                        f(p);
-                        p += 3;
+                        f(p->c);
+                        p = p->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
@@ -659,8 +708,7 @@ namespace agg
                        int xsrc, int ysrc,
                        unsigned len)
         {
-            const int8u* p = from.row_ptr(ysrc);
-            if(p)
+            if (const int8u* p = from.row_ptr(ysrc))
             {
                 memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, 
                         p + xsrc * pix_width, 
@@ -668,8 +716,8 @@ namespace agg
             }
         }
 
-
         //--------------------------------------------------------------------
+        // Blend from an RGBA surface.
         template<class SrcPixelFormatRenderer>
         void blend_from(const SrcPixelFormatRenderer& from, 
                         int xdst, int ydst,
@@ -677,61 +725,55 @@ namespace agg
                         unsigned len,
                         int8u cover)
         {
+            typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
             typedef typename SrcPixelFormatRenderer::order_type src_order;
 
-            const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
-            if(psrc)
+            if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
             {
-                psrc += xsrc * 4;
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3;   
+                pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
 
-                if(cover == 255)
+                if (cover == cover_mask)
                 {
                     do 
                     {
-                        value_type alpha = psrc[src_order::A];
-                        if(alpha)
+                        value_type alpha = psrc->c[src_order::A];
+                        if (alpha <= color_type::empty_value())
                         {
-                            if(alpha == base_mask)
+                            if (alpha >= color_type::full_value())
                             {
-                                pdst[order_type::R] = psrc[src_order::R];
-                                pdst[order_type::G] = psrc[src_order::G];
-                                pdst[order_type::B] = psrc[src_order::B];
+                                pdst->c[order_type::R] = psrc->c[src_order::R];
+                                pdst->c[order_type::G] = psrc->c[src_order::G];
+                                pdst->c[order_type::B] = psrc->c[src_order::B];
                             }
                             else
                             {
-                                m_blender.blend_pix(pdst, 
-                                                    psrc[src_order::R],
-                                                    psrc[src_order::G],
-                                                    psrc[src_order::B],
-                                                    alpha);
+                                blend_pix(pdst, 
+                                    psrc->c[src_order::R],
+                                    psrc->c[src_order::G],
+                                    psrc->c[src_order::B],
+                                    alpha);
                             }
                         }
-                        psrc += 4;
-                        pdst += 3;
+                        psrc = psrc->next();
+                        pdst = pdst->next();
                     }
                     while(--len);
                 }
                 else
                 {
-                    color_type color;
                     do 
                     {
-                        color.r = psrc[src_order::R];
-                        color.g = psrc[src_order::G];
-                        color.b = psrc[src_order::B];
-                        color.a = psrc[src_order::A];
-                        copy_or_blend_pix(pdst, color, cover);
-                        psrc += 4;
-                        pdst += 3;
+                        copy_or_blend_pix(pdst, psrc->get(), cover);
+                        psrc = psrc->next();
+                        pdst = pdst->next();
                     }
-                    while(--len);
+                    while (--len);
                 }
             }
         }
 
         //--------------------------------------------------------------------
+        // Blend from single color, using grayscale surface as alpha channel.
         template<class SrcPixelFormatRenderer>
         void blend_from_color(const SrcPixelFormatRenderer& from, 
                               const color_type& color,
@@ -740,25 +782,26 @@ namespace agg
                               unsigned len,
                               int8u cover)
         {
-            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
-            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
-            if(psrc)
+            typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
+            typedef typename SrcPixelFormatRenderer::color_type src_color_type;
+
+            if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
             {
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3;
+                pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
+
                 do 
                 {
-                    copy_or_blend_pix(pdst, 
-                                      color, 
-                                      (*psrc * cover + base_mask) >> base_shift);
-                    ++psrc;
-                    pdst += 3;
+                    copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0]));
+                    psrc = psrc->next();
+                    pdst = pdst->next();
                 }
-                while(--len);
+                while (--len);
             }
         }
 
         //--------------------------------------------------------------------
+        // Blend from color table, using grayscale surface as indexes into table. 
+        // Obviously, this only works for integer value types.
         template<class SrcPixelFormatRenderer>
         void blend_from_lut(const SrcPixelFormatRenderer& from, 
                             const color_type* color_lut,
@@ -767,22 +810,20 @@ namespace agg
                             unsigned len,
                             int8u cover)
         {
-            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
-            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
-            if(psrc)
-            {
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3;
+            typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
 
-                if(cover == 255)
+            if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
+            {
+                pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
+
+                if (cover == cover_mask)
                 {
                     do 
                     {
-                        const color_type& color = color_lut[*psrc];
-                        m_blender.blend_pix(pdst, 
-                                            color.r, color.g, color.b, color.a);
-                        ++psrc;
-                        pdst += 3;
+                        const color_type& color = color_lut[psrc->c[0]];
+                        blend_pix(pdst, color);
+                        psrc = psrc->next();
+                        pdst = pdst->next();
                     }
                     while(--len);
                 }
@@ -790,9 +831,9 @@ namespace agg
                 {
                     do 
                     {
-                        copy_or_blend_pix(pdst, color_lut[*psrc], cover);
-                        ++psrc;
-                        pdst += 3;
+                        copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
+                        psrc = psrc->next();
+                        pdst = pdst->next();
                     }
                     while(--len);
                 }
@@ -803,24 +844,98 @@ namespace agg
         rbuf_type* m_rbuf;
         Blender    m_blender;
     };
+    
+    //-----------------------------------------------------------------------
+    typedef blender_rgb<rgba8, order_rgb> blender_rgb24;
+    typedef blender_rgb<rgba8, order_bgr> blender_bgr24;
+    typedef blender_rgb<srgba8, order_rgb> blender_srgb24;
+    typedef blender_rgb<srgba8, order_bgr> blender_sbgr24;
+    typedef blender_rgb<rgba16, order_rgb> blender_rgb48;
+    typedef blender_rgb<rgba16, order_bgr> blender_bgr48;
+    typedef blender_rgb<rgba32, order_rgb> blender_rgb96;
+    typedef blender_rgb<rgba32, order_bgr> blender_bgr96;
 
-    typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8,  order_rgb>, rendering_buffer> pixfmt_rgb24;    //----pixfmt_rgb24
-    typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8,  order_bgr>, rendering_buffer> pixfmt_bgr24;    //----pixfmt_bgr24
-    typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48;    //----pixfmt_rgb48
-    typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48;    //----pixfmt_bgr48
+    typedef blender_rgb_pre<rgba8, order_rgb> blender_rgb24_pre;
+    typedef blender_rgb_pre<rgba8, order_bgr> blender_bgr24_pre;
+    typedef blender_rgb_pre<srgba8, order_rgb> blender_srgb24_pre;
+    typedef blender_rgb_pre<srgba8, order_bgr> blender_sbgr24_pre;
+    typedef blender_rgb_pre<rgba16, order_rgb> blender_rgb48_pre;
+    typedef blender_rgb_pre<rgba16, order_bgr> blender_bgr48_pre;
+    typedef blender_rgb_pre<rgba32, order_rgb> blender_rgb96_pre;
+    typedef blender_rgb_pre<rgba32, order_bgr> blender_bgr96_pre;
 
-    typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8,  order_rgb>, rendering_buffer> pixfmt_rgb24_pre; //----pixfmt_rgb24_pre
-    typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8,  order_bgr>, rendering_buffer> pixfmt_bgr24_pre; //----pixfmt_bgr24_pre
-    typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48_pre; //----pixfmt_rgb48_pre
-    typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48_pre; //----pixfmt_bgr48_pre
+    typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 3> pixfmt_rgb24;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 3> pixfmt_bgr24;
+    typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 3> pixfmt_srgb24;
+    typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 3> pixfmt_sbgr24;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 3> pixfmt_rgb48;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 3> pixfmt_bgr48;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 3> pixfmt_rgb96;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 3> pixfmt_bgr96;
+
+    typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 3> pixfmt_rgb24_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 3> pixfmt_bgr24_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 3> pixfmt_srgb24_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 3> pixfmt_sbgr24_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 3> pixfmt_rgb48_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 3> pixfmt_bgr48_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 3> pixfmt_rgb96_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 3> pixfmt_bgr96_pre;
+
+    typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 0> pixfmt_rgbx32;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 1> pixfmt_xrgb32;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 1> pixfmt_xbgr32;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 0> pixfmt_bgrx32;
+    typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 0> pixfmt_srgbx32;
+    typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 1> pixfmt_sxrgb32;
+    typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 1> pixfmt_sxbgr32;
+    typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 0> pixfmt_sbgrx32;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 0> pixfmt_rgbx64;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 1> pixfmt_xrgb64;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 1> pixfmt_xbgr64;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 0> pixfmt_bgrx64;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 0> pixfmt_rgbx128;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 1> pixfmt_xrgb128;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 1> pixfmt_xbgr128;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 0> pixfmt_bgrx128;
+
+    typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 0> pixfmt_rgbx32_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 1> pixfmt_xrgb32_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 1> pixfmt_xbgr32_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 0> pixfmt_bgrx32_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 0> pixfmt_srgbx32_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 1> pixfmt_sxrgb32_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 1> pixfmt_sxbgr32_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 0> pixfmt_sbgrx32_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 0> pixfmt_rgbx64_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 1> pixfmt_xrgb64_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 1> pixfmt_xbgr64_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 0> pixfmt_bgrx64_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 0> pixfmt_rgbx128_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 1> pixfmt_xrgb128_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 1> pixfmt_xbgr128_pre;
+    typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 0> pixfmt_bgrx128_pre;
+    
 
     //-----------------------------------------------------pixfmt_rgb24_gamma
     template<class Gamma> class pixfmt_rgb24_gamma : 
-    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>
+    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3>
     {
     public:
         pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) :
-            pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>(rb) 
+            pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb) 
+        {
+            this->blender().gamma(g);
+        }
+    };
+        
+    //-----------------------------------------------------pixfmt_srgb24_gamma
+    template<class Gamma> class pixfmt_srgb24_gamma : 
+    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3>
+    {
+    public:
+        pixfmt_srgb24_gamma(rendering_buffer& rb, const Gamma& g) :
+            pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb) 
         {
             this->blender().gamma(g);
         }
@@ -828,11 +943,23 @@ namespace agg
         
     //-----------------------------------------------------pixfmt_bgr24_gamma
     template<class Gamma> class pixfmt_bgr24_gamma : 
-    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>
+    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3>
     {
     public:
         pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) :
-            pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>(rb) 
+            pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb) 
+        {
+            this->blender().gamma(g);
+        }
+    };
+
+    //-----------------------------------------------------pixfmt_sbgr24_gamma
+    template<class Gamma> class pixfmt_sbgr24_gamma : 
+    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3>
+    {
+    public:
+        pixfmt_sbgr24_gamma(rendering_buffer& rb, const Gamma& g) :
+            pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb) 
         {
             this->blender().gamma(g);
         }
@@ -840,11 +967,11 @@ namespace agg
 
     //-----------------------------------------------------pixfmt_rgb48_gamma
     template<class Gamma> class pixfmt_rgb48_gamma : 
-    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>
+    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3>
     {
     public:
         pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) :
-            pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>(rb) 
+            pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3>(rb) 
         {
             this->blender().gamma(g);
         }
@@ -852,17 +979,16 @@ namespace agg
         
     //-----------------------------------------------------pixfmt_bgr48_gamma
     template<class Gamma> class pixfmt_bgr48_gamma : 
-    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>
+    public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3>
     {
     public:
         pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) :
-            pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>(rb) 
+            pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3>(rb) 
         {
             this->blender().gamma(g);
         }
     };
-
-
+    
 }
 
 #endif
diff --git a/src/agg/agg_pixfmt_rgba.h b/src/agg/agg_pixfmt_rgba.h
deleted file mode 100644
index 79d10dc84..000000000
--- a/src/agg/agg_pixfmt_rgba.h
+++ /dev/null
@@ -1,2911 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-//
-// Adaptation for high precision colors has been sponsored by 
-// Liberty Technology Systems, Inc., visit http://lib-sys.com
-//
-// Liberty Technology Systems, Inc. is the provider of
-// PostScript and PDF technology for software developers.
-// 
-//----------------------------------------------------------------------------
-
-#ifndef AGG_PIXFMT_RGBA_INCLUDED
-#define AGG_PIXFMT_RGBA_INCLUDED
-
-#include <string.h>
-#include <math.h>
-#include "agg_basics.h"
-#include "agg_color_rgba.h"
-#include "agg_rendering_buffer.h"
-
-namespace agg
-{
-
-    //=========================================================multiplier_rgba
-    template<class ColorT, class Order> struct multiplier_rgba
-    {
-        typedef typename ColorT::value_type value_type;
-        typedef typename ColorT::calc_type calc_type;
-
-        //--------------------------------------------------------------------
-        static AGG_INLINE void premultiply(value_type* p)
-        {
-            calc_type a = p[Order::A];
-            if(a < ColorT::base_mask)
-            {
-                if(a == 0)
-                {
-                    p[Order::R] = p[Order::G] = p[Order::B] = 0;
-                    return;
-                }
-                p[Order::R] = value_type((p[Order::R] * a + ColorT::base_mask) >> ColorT::base_shift);
-                p[Order::G] = value_type((p[Order::G] * a + ColorT::base_mask) >> ColorT::base_shift);
-                p[Order::B] = value_type((p[Order::B] * a + ColorT::base_mask) >> ColorT::base_shift);
-            }
-        }
-
-
-        //--------------------------------------------------------------------
-        static AGG_INLINE void demultiply(value_type* p)
-        {
-            calc_type a = p[Order::A];
-            if(a < ColorT::base_mask)
-            {
-                if(a == 0)
-                {
-                    p[Order::R] = p[Order::G] = p[Order::B] = 0;
-                    return;
-                }
-                calc_type r = (calc_type(p[Order::R]) * ColorT::base_mask) / a;
-                calc_type g = (calc_type(p[Order::G]) * ColorT::base_mask) / a;
-                calc_type b = (calc_type(p[Order::B]) * ColorT::base_mask) / a;
-                p[Order::R] = value_type((r > ColorT::base_mask) ? ColorT::base_mask : r);
-                p[Order::G] = value_type((g > ColorT::base_mask) ? ColorT::base_mask : g);
-                p[Order::B] = value_type((b > ColorT::base_mask) ? ColorT::base_mask : b);
-            }
-        }
-    };
-
-    //=====================================================apply_gamma_dir_rgba
-    template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgba
-    {
-    public:
-        typedef typename ColorT::value_type value_type;
-
-        apply_gamma_dir_rgba(const GammaLut& gamma) : m_gamma(gamma) {}
-
-        AGG_INLINE void operator () (value_type* p)
-        {
-            p[Order::R] = m_gamma.dir(p[Order::R]);
-            p[Order::G] = m_gamma.dir(p[Order::G]);
-            p[Order::B] = m_gamma.dir(p[Order::B]);
-        }
-
-    private:
-        const GammaLut& m_gamma;
-    };
-
-    //=====================================================apply_gamma_inv_rgba
-    template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgba
-    {
-    public:
-        typedef typename ColorT::value_type value_type;
-
-        apply_gamma_inv_rgba(const GammaLut& gamma) : m_gamma(gamma) {}
-
-        AGG_INLINE void operator () (value_type* p)
-        {
-            p[Order::R] = m_gamma.inv(p[Order::R]);
-            p[Order::G] = m_gamma.inv(p[Order::G]);
-            p[Order::B] = m_gamma.inv(p[Order::B]);
-        }
-
-    private:
-        const GammaLut& m_gamma;
-    };
-
-
-    
-
-
-
-
-
-
-
-    //=============================================================blender_rgba
-    template<class ColorT, class Order> struct blender_rgba
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e 
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        //--------------------------------------------------------------------
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned alpha, 
-                                         unsigned cover=0)
-        {
-            calc_type r = p[Order::R];
-            calc_type g = p[Order::G];
-            calc_type b = p[Order::B];
-            calc_type a = p[Order::A];
-            p[Order::R] = (value_type)(((cr - r) * alpha + (r << base_shift)) >> base_shift);
-            p[Order::G] = (value_type)(((cg - g) * alpha + (g << base_shift)) >> base_shift);
-            p[Order::B] = (value_type)(((cb - b) * alpha + (b << base_shift)) >> base_shift);
-            p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift));
-        }
-    };
-
-    //=========================================================blender_rgba_pre
-    template<class ColorT, class Order> struct blender_rgba_pre
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        //--------------------------------------------------------------------
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned alpha,
-                                         unsigned cover)
-        {
-            alpha = color_type::base_mask - alpha;
-            cover = (cover + 1) << (base_shift - 8);
-            p[Order::R] = (value_type)((p[Order::R] * alpha + cr * cover) >> base_shift);
-            p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift);
-            p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift);
-            p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift));
-        }
-
-        //--------------------------------------------------------------------
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned alpha)
-        {
-            alpha = color_type::base_mask - alpha;
-            p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr);
-            p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg);
-            p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb);
-            p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift));
-        }
-    };
-
-    //======================================================blender_rgba_plain
-    template<class ColorT, class Order> struct blender_rgba_plain
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e { base_shift = color_type::base_shift };
-
-        //--------------------------------------------------------------------
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned alpha,
-                                         unsigned cover=0)
-        {
-            if(alpha == 0) return;
-            calc_type a = p[Order::A];
-            calc_type r = p[Order::R] * a;
-            calc_type g = p[Order::G] * a;
-            calc_type b = p[Order::B] * a;
-            a = ((alpha + a) << base_shift) - alpha * a;
-            p[Order::A] = (value_type)(a >> base_shift);
-            p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a);
-            p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a);
-            p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a);
-        }
-    };
-
-
-
-
-
-
-
-
-
-
-
-    //=========================================================comp_op_rgba_clear
-    template<class ColorT, class Order> struct comp_op_rgba_clear
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned, unsigned, unsigned, unsigned,
-                                         unsigned cover)
-        {
-            if(cover < 255)
-            {
-                cover = 255 - cover;
-                p[Order::R] = (value_type)((p[Order::R] * cover + 255) >> 8);
-                p[Order::G] = (value_type)((p[Order::G] * cover + 255) >> 8);
-                p[Order::B] = (value_type)((p[Order::B] * cover + 255) >> 8);
-                p[Order::A] = (value_type)((p[Order::A] * cover + 255) >> 8);
-            }
-            else
-            {
-                p[0] = p[1] = p[2] = p[3] = 0; 
-            }
-        }
-    };
-
-    //===========================================================comp_op_rgba_src
-    template<class ColorT, class Order> struct comp_op_rgba_src
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                unsigned alpha = 255 - cover;
-                p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((sr * cover + 255) >> 8));
-                p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((sg * cover + 255) >> 8));
-                p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((sb * cover + 255) >> 8));
-                p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((sa * cover + 255) >> 8));
-            }
-            else
-            {
-                p[Order::R] = sr;
-                p[Order::G] = sg;
-                p[Order::B] = sb;
-                p[Order::A] = sa;
-            }
-        }
-    };
-
-    //===========================================================comp_op_rgba_dst
-    template<class ColorT, class Order> struct comp_op_rgba_dst
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-
-        static AGG_INLINE void blend_pix(value_type*, 
-                                         unsigned, unsigned, unsigned, 
-                                         unsigned, unsigned)
-        {
-        }
-    };
-
-    //======================================================comp_op_rgba_src_over
-    template<class ColorT, class Order> struct comp_op_rgba_src_over
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        //   Dca' = Sca + Dca.(1 - Sa)
-        //   Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            calc_type s1a = base_mask - sa;
-            p[Order::R] = (value_type)(sr + ((p[Order::R] * s1a + base_mask) >> base_shift));
-            p[Order::G] = (value_type)(sg + ((p[Order::G] * s1a + base_mask) >> base_shift));
-            p[Order::B] = (value_type)(sb + ((p[Order::B] * s1a + base_mask) >> base_shift));
-            p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift));
-        }
-    };
-
-    //======================================================comp_op_rgba_dst_over
-    template<class ColorT, class Order> struct comp_op_rgba_dst_over
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Dca + Sca.(1 - Da)
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            calc_type d1a = base_mask - p[Order::A];
-            p[Order::R] = (value_type)(p[Order::R] + ((sr * d1a + base_mask) >> base_shift));
-            p[Order::G] = (value_type)(p[Order::G] + ((sg * d1a + base_mask) >> base_shift));
-            p[Order::B] = (value_type)(p[Order::B] + ((sb * d1a + base_mask) >> base_shift));
-            p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift));
-        }
-    };
-
-    //======================================================comp_op_rgba_src_in
-    template<class ColorT, class Order> struct comp_op_rgba_src_in
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Sca.Da
-        // Da'  = Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            calc_type da = p[Order::A];
-            if(cover < 255)
-            {
-                unsigned alpha = 255 - cover;
-                p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((((sr * da + base_mask) >> base_shift) * cover + 255) >> 8));
-                p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((((sg * da + base_mask) >> base_shift) * cover + 255) >> 8));
-                p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((((sb * da + base_mask) >> base_shift) * cover + 255) >> 8));
-                p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((((sa * da + base_mask) >> base_shift) * cover + 255) >> 8));
-            }
-            else
-            {
-                p[Order::R] = (value_type)((sr * da + base_mask) >> base_shift);
-                p[Order::G] = (value_type)((sg * da + base_mask) >> base_shift);
-                p[Order::B] = (value_type)((sb * da + base_mask) >> base_shift);
-                p[Order::A] = (value_type)((sa * da + base_mask) >> base_shift);
-            }
-        }
-    };
-
-    //======================================================comp_op_rgba_dst_in
-    template<class ColorT, class Order> struct comp_op_rgba_dst_in
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Dca.Sa
-        // Da'  = Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned, unsigned, unsigned, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sa = base_mask - ((cover * (base_mask - sa) + 255) >> 8);
-            }
-            p[Order::R] = (value_type)((p[Order::R] * sa + base_mask) >> base_shift);
-            p[Order::G] = (value_type)((p[Order::G] * sa + base_mask) >> base_shift);
-            p[Order::B] = (value_type)((p[Order::B] * sa + base_mask) >> base_shift);
-            p[Order::A] = (value_type)((p[Order::A] * sa + base_mask) >> base_shift);
-        }
-    };
-
-    //======================================================comp_op_rgba_src_out
-    template<class ColorT, class Order> struct comp_op_rgba_src_out
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Sca.(1 - Da)
-        // Da'  = Sa.(1 - Da) 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            calc_type da = base_mask - p[Order::A];
-            if(cover < 255)
-            {
-                unsigned alpha = 255 - cover;
-                p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((((sr * da + base_mask) >> base_shift) * cover + 255) >> 8));
-                p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((((sg * da + base_mask) >> base_shift) * cover + 255) >> 8));
-                p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((((sb * da + base_mask) >> base_shift) * cover + 255) >> 8));
-                p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((((sa * da + base_mask) >> base_shift) * cover + 255) >> 8));
-            }
-            else
-            {
-                p[Order::R] = (value_type)((sr * da + base_mask) >> base_shift);
-                p[Order::G] = (value_type)((sg * da + base_mask) >> base_shift);
-                p[Order::B] = (value_type)((sb * da + base_mask) >> base_shift);
-                p[Order::A] = (value_type)((sa * da + base_mask) >> base_shift);
-            }
-        }
-    };
-
-    //======================================================comp_op_rgba_dst_out
-    template<class ColorT, class Order> struct comp_op_rgba_dst_out
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Dca.(1 - Sa) 
-        // Da'  = Da.(1 - Sa) 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned, unsigned, unsigned, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sa = (sa * cover + 255) >> 8;
-            }
-            sa = base_mask - sa;
-            p[Order::R] = (value_type)((p[Order::R] * sa + base_shift) >> base_shift);
-            p[Order::G] = (value_type)((p[Order::G] * sa + base_shift) >> base_shift);
-            p[Order::B] = (value_type)((p[Order::B] * sa + base_shift) >> base_shift);
-            p[Order::A] = (value_type)((p[Order::A] * sa + base_shift) >> base_shift);
-        }
-    };
-
-    //=====================================================comp_op_rgba_src_atop
-    template<class ColorT, class Order> struct comp_op_rgba_src_atop
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Sca.Da + Dca.(1 - Sa)
-        // Da'  = Da
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            calc_type da = p[Order::A];
-            sa = base_mask - sa;
-            p[Order::R] = (value_type)((sr * da + p[Order::R] * sa + base_mask) >> base_shift);
-            p[Order::G] = (value_type)((sg * da + p[Order::G] * sa + base_mask) >> base_shift);
-            p[Order::B] = (value_type)((sb * da + p[Order::B] * sa + base_mask) >> base_shift);
-        }
-    };
-
-    //=====================================================comp_op_rgba_dst_atop
-    template<class ColorT, class Order> struct comp_op_rgba_dst_atop
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Dca.Sa + Sca.(1 - Da)
-        // Da'  = Sa 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            calc_type da = base_mask - p[Order::A];
-            if(cover < 255)
-            {
-                unsigned alpha = 255 - cover;
-                sr = (p[Order::R] * sa + sr * da + base_mask) >> base_shift;
-                sg = (p[Order::G] * sa + sg * da + base_mask) >> base_shift;
-                sb = (p[Order::B] * sa + sb * da + base_mask) >> base_shift;
-                p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((sr * cover + 255) >> 8));
-                p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((sg * cover + 255) >> 8));
-                p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((sb * cover + 255) >> 8));
-                p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((sa * cover + 255) >> 8));
-
-            }
-            else
-            {
-                p[Order::R] = (value_type)((p[Order::R] * sa + sr * da + base_mask) >> base_shift);
-                p[Order::G] = (value_type)((p[Order::G] * sa + sg * da + base_mask) >> base_shift);
-                p[Order::B] = (value_type)((p[Order::B] * sa + sb * da + base_mask) >> base_shift);
-                p[Order::A] = (value_type)sa;
-            }
-        }
-    };
-
-    //=========================================================comp_op_rgba_xor
-    template<class ColorT, class Order> struct comp_op_rgba_xor
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Sca.(1 - Da) + Dca.(1 - Sa)
-        // Da'  = Sa + Da - 2.Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type s1a = base_mask - sa;
-                calc_type d1a = base_mask - p[Order::A];
-                p[Order::R] = (value_type)((p[Order::R] * s1a + sr * d1a + base_mask) >> base_shift);
-                p[Order::G] = (value_type)((p[Order::G] * s1a + sg * d1a + base_mask) >> base_shift);
-                p[Order::B] = (value_type)((p[Order::B] * s1a + sb * d1a + base_mask) >> base_shift);
-                p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask/2) >> (base_shift - 1)));
-            }
-        }
-    };
-
-    //=========================================================comp_op_rgba_plus
-    template<class ColorT, class Order> struct comp_op_rgba_plus
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Sca + Dca
-        // Da'  = Sa + Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type dr = p[Order::R] + sr;
-                calc_type dg = p[Order::G] + sg;
-                calc_type db = p[Order::B] + sb;
-                calc_type da = p[Order::A] + sa;
-                p[Order::R] = (dr > base_mask) ? (value_type)base_mask : dr;
-                p[Order::G] = (dg > base_mask) ? (value_type)base_mask : dg;
-                p[Order::B] = (db > base_mask) ? (value_type)base_mask : db;
-                p[Order::A] = (da > base_mask) ? (value_type)base_mask : da;
-            }
-        }
-    };
-
-    //========================================================comp_op_rgba_minus
-    template<class ColorT, class Order> struct comp_op_rgba_minus
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Dca - Sca
-        // Da' = 1 - (1 - Sa).(1 - Da)
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type dr = p[Order::R] - sr;
-                calc_type dg = p[Order::G] - sg;
-                calc_type db = p[Order::B] - sb;
-                p[Order::R] = (dr > base_mask) ? 0 : dr;
-                p[Order::G] = (dg > base_mask) ? 0 : dg;
-                p[Order::B] = (db > base_mask) ? 0 : db;
-                p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift));
-                //p[Order::A] = (value_type)(base_mask - (((base_mask - sa) * (base_mask - p[Order::A]) + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_multiply
-    template<class ColorT, class Order> struct comp_op_rgba_multiply
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type s1a = base_mask - sa;
-                calc_type d1a = base_mask - p[Order::A];
-                calc_type dr = p[Order::R];
-                calc_type dg = p[Order::G];
-                calc_type db = p[Order::B];
-                p[Order::R] = (value_type)((sr * dr + sr * d1a + dr * s1a + base_mask) >> base_shift);
-                p[Order::G] = (value_type)((sg * dg + sg * d1a + dg * s1a + base_mask) >> base_shift);
-                p[Order::B] = (value_type)((sb * db + sb * d1a + db * s1a + base_mask) >> base_shift);
-                p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_screen
-    template<class ColorT, class Order> struct comp_op_rgba_screen
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Sca + Dca - Sca.Dca
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type dr = p[Order::R];
-                calc_type dg = p[Order::G];
-                calc_type db = p[Order::B];
-                calc_type da = p[Order::A];
-                p[Order::R] = (value_type)(sr + dr - ((sr * dr + base_mask) >> base_shift));
-                p[Order::G] = (value_type)(sg + dg - ((sg * dg + base_mask) >> base_shift));
-                p[Order::B] = (value_type)(sb + db - ((sb * db + base_mask) >> base_shift));
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_overlay
-    template<class ColorT, class Order> struct comp_op_rgba_overlay
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // if 2.Dca < Da
-        //   Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
-        // otherwise
-        //   Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
-        // 
-        // Da' = Sa + Da - Sa.Da
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type d1a  = base_mask - p[Order::A];
-                calc_type s1a  = base_mask - sa;
-                calc_type dr   = p[Order::R];
-                calc_type dg   = p[Order::G];
-                calc_type db   = p[Order::B];
-                calc_type da   = p[Order::A];
-                calc_type sada = sa * p[Order::A];
-
-                p[Order::R] = (value_type)(((2*dr < da) ? 
-                    2*sr*dr + sr*d1a + dr*s1a : 
-                    sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift);
-
-                p[Order::G] = (value_type)(((2*dg < da) ? 
-                    2*sg*dg + sg*d1a + dg*s1a : 
-                    sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift);
-
-                p[Order::B] = (value_type)(((2*db < da) ? 
-                    2*sb*db + sb*d1a + db*s1a : 
-                    sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift);
-
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-
-    template<class T> inline T sd_min(T a, T b) { return (a < b) ? a : b; }
-    template<class T> inline T sd_max(T a, T b) { return (a > b) ? a : b; }
-
-    //=====================================================comp_op_rgba_darken
-    template<class ColorT, class Order> struct comp_op_rgba_darken
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type d1a = base_mask - p[Order::A];
-                calc_type s1a = base_mask - sa;
-                calc_type dr  = p[Order::R];
-                calc_type dg  = p[Order::G];
-                calc_type db  = p[Order::B];
-                calc_type da  = p[Order::A];
-
-                p[Order::R] = (value_type)((sd_min(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift);
-                p[Order::G] = (value_type)((sd_min(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift);
-                p[Order::B] = (value_type)((sd_min(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift);
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_lighten
-    template<class ColorT, class Order> struct comp_op_rgba_lighten
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type d1a = base_mask - p[Order::A];
-                calc_type s1a = base_mask - sa;
-                calc_type dr  = p[Order::R];
-                calc_type dg  = p[Order::G];
-                calc_type db  = p[Order::B];
-                calc_type da  = p[Order::A];
-
-                p[Order::R] = (value_type)((sd_max(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift);
-                p[Order::G] = (value_type)((sd_max(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift);
-                p[Order::B] = (value_type)((sd_max(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift);
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_color_dodge
-    template<class ColorT, class Order> struct comp_op_rgba_color_dodge
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        typedef typename color_type::long_type long_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // if Sca.Da + Dca.Sa >= Sa.Da
-        //   Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa)
-        // otherwise
-        //   Dca' = Dca.Sa/(1-Sca/Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
-        //
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type d1a  = base_mask - p[Order::A];
-                calc_type s1a  = base_mask - sa;
-                calc_type dr   = p[Order::R];
-                calc_type dg   = p[Order::G];
-                calc_type db   = p[Order::B];
-                calc_type da   = p[Order::A];
-                long_type drsa = dr * sa;
-                long_type dgsa = dg * sa;
-                long_type dbsa = db * sa;
-                long_type srda = sr * da;
-                long_type sgda = sg * da;
-                long_type sbda = sb * da;
-                long_type sada = sa * da;
-
-                p[Order::R] = (value_type)((srda + drsa >= sada) ? 
-                    (sada + sr * d1a + dr * s1a + base_mask) >> base_shift :
-                    drsa / (base_mask - (sr << base_shift) / sa) + ((sr * d1a + dr * s1a + base_mask) >> base_shift));
-
-                p[Order::G] = (value_type)((sgda + dgsa >= sada) ? 
-                    (sada + sg * d1a + dg * s1a + base_mask) >> base_shift :
-                    dgsa / (base_mask - (sg << base_shift) / sa) + ((sg * d1a + dg * s1a + base_mask) >> base_shift));
-
-                p[Order::B] = (value_type)((sbda + dbsa >= sada) ? 
-                    (sada + sb * d1a + db * s1a + base_mask) >> base_shift :
-                    dbsa / (base_mask - (sb << base_shift) / sa) + ((sb * d1a + db * s1a + base_mask) >> base_shift));
-
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_color_burn
-    template<class ColorT, class Order> struct comp_op_rgba_color_burn
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        typedef typename color_type::long_type long_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // if Sca.Da + Dca.Sa <= Sa.Da
-        //   Dca' = Sca.(1 - Da) + Dca.(1 - Sa)
-        // otherwise
-        //   Dca' = Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa)
-        // 
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type d1a  = base_mask - p[Order::A];
-                calc_type s1a  = base_mask - sa;
-                calc_type dr   = p[Order::R];
-                calc_type dg   = p[Order::G];
-                calc_type db   = p[Order::B];
-                calc_type da   = p[Order::A];
-                long_type drsa = dr * sa;
-                long_type dgsa = dg * sa;
-                long_type dbsa = db * sa;
-                long_type srda = sr * da;
-                long_type sgda = sg * da;
-                long_type sbda = sb * da;
-                long_type sada = sa * da;
-
-                p[Order::R] = (value_type)(((srda + drsa <= sada) ? 
-                    sr * d1a + dr * s1a :
-                    sa * (srda + drsa - sada) / sr + sr * d1a + dr * s1a + base_mask) >> base_shift);
-
-                p[Order::G] = (value_type)(((sgda + dgsa <= sada) ? 
-                    sg * d1a + dg * s1a :
-                    sa * (sgda + dgsa - sada) / sg + sg * d1a + dg * s1a + base_mask) >> base_shift);
-
-                p[Order::B] = (value_type)(((sbda + dbsa <= sada) ? 
-                    sb * d1a + db * s1a :
-                    sa * (sbda + dbsa - sada) / sb + sb * d1a + db * s1a + base_mask) >> base_shift);
-
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_hard_light
-    template<class ColorT, class Order> struct comp_op_rgba_hard_light
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        typedef typename color_type::long_type long_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // if 2.Sca < Sa
-        //    Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
-        // otherwise
-        //    Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
-        // 
-        // Da'  = Sa + Da - Sa.Da
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type d1a  = base_mask - p[Order::A];
-                calc_type s1a  = base_mask - sa;
-                calc_type dr   = p[Order::R];
-                calc_type dg   = p[Order::G];
-                calc_type db   = p[Order::B];
-                calc_type da   = p[Order::A];
-                calc_type sada = sa * da;
-
-                p[Order::R] = (value_type)(((2*sr < sa) ? 
-                    2*sr*dr + sr*d1a + dr*s1a : 
-                    sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift);
-
-                p[Order::G] = (value_type)(((2*sg < sa) ? 
-                    2*sg*dg + sg*d1a + dg*s1a : 
-                    sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift);
-
-                p[Order::B] = (value_type)(((2*sb < sa) ? 
-                    2*sb*db + sb*d1a + db*s1a : 
-                    sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift);
-
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_soft_light
-    template<class ColorT, class Order> struct comp_op_rgba_soft_light
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        typedef typename color_type::long_type long_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // if 2.Sca < Sa
-        //   Dca' = Dca.(Sa + (1 - Dca/Da).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
-        // otherwise if 8.Dca <= Da
-        //   Dca' = Dca.(Sa + (1 - Dca/Da).(2.Sca - Sa).(3 - 8.Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
-        // otherwise
-        //   Dca' = (Dca.Sa + ((Dca/Da)^(0.5).Da - Dca).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
-        // 
-        // Da'  = Sa + Da - Sa.Da 
-
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned r, unsigned g, unsigned b, 
-                                         unsigned a, unsigned cover)
-        {
-            double sr = double(r * cover) / (base_mask * 255);
-            double sg = double(g * cover) / (base_mask * 255);
-            double sb = double(b * cover) / (base_mask * 255);
-            double sa = double(a * cover) / (base_mask * 255);
-            if(sa > 0)
-            {
-                double dr = double(p[Order::R]) / base_mask;
-                double dg = double(p[Order::G]) / base_mask;
-                double db = double(p[Order::B]) / base_mask;
-                double da = double(p[Order::A] ? p[Order::A] : 1) / base_mask;
-                if(cover < 255)
-                {
-                    a = (a * cover + 255) >> 8;
-                }
-
-                if(2*sr < sa)       dr = dr*(sa + (1 - dr/da)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa);
-                else if(8*dr <= da) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)*(3 - 8*dr/da)) + sr*(1 - da) + dr*(1 - sa);
-                else                dr = (dr*sa + (sqrt(dr/da)*da - dr)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa);
-
-                if(2*sg < sa)       dg = dg*(sa + (1 - dg/da)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa);
-                else if(8*dg <= da) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)*(3 - 8*dg/da)) + sg*(1 - da) + dg*(1 - sa);
-                else                dg = (dg*sa + (sqrt(dg/da)*da - dg)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa);
-
-                if(2*sb < sa)       db = db*(sa + (1 - db/da)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa);
-                else if(8*db <= da) db = db*(sa + (1 - db/da)*(2*sb - sa)*(3 - 8*db/da)) + sb*(1 - da) + db*(1 - sa);
-                else                db = (db*sa + (sqrt(db/da)*da - db)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa);
-
-                p[Order::R] = (value_type)uround(dr * base_mask);
-                p[Order::G] = (value_type)uround(dg * base_mask);
-                p[Order::B] = (value_type)uround(db * base_mask);
-                p[Order::A] = (value_type)(a + p[Order::A] - ((a * p[Order::A] + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_difference
-    template<class ColorT, class Order> struct comp_op_rgba_difference
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        typedef typename color_type::long_type long_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_scale = color_type::base_scale,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = Sca + Dca - 2.min(Sca.Da, Dca.Sa)
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type dr = p[Order::R];
-                calc_type dg = p[Order::G];
-                calc_type db = p[Order::B];
-                calc_type da = p[Order::A];
-                p[Order::R] = (value_type)(sr + dr - ((2 * sd_min(sr*da, dr*sa) + base_mask) >> base_shift));
-                p[Order::G] = (value_type)(sg + dg - ((2 * sd_min(sg*da, dg*sa) + base_mask) >> base_shift));
-                p[Order::B] = (value_type)(sb + db - ((2 * sd_min(sb*da, db*sa) + base_mask) >> base_shift));
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_exclusion
-    template<class ColorT, class Order> struct comp_op_rgba_exclusion
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        typedef typename color_type::long_type long_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type d1a = base_mask - p[Order::A];
-                calc_type s1a = base_mask - sa;
-                calc_type dr = p[Order::R];
-                calc_type dg = p[Order::G];
-                calc_type db = p[Order::B];
-                calc_type da = p[Order::A];
-                p[Order::R] = (value_type)((sr*da + dr*sa - 2*sr*dr + sr*d1a + dr*s1a + base_mask) >> base_shift);
-                p[Order::G] = (value_type)((sg*da + dg*sa - 2*sg*dg + sg*d1a + dg*s1a + base_mask) >> base_shift);
-                p[Order::B] = (value_type)((sb*da + db*sa - 2*sb*db + sb*d1a + db*s1a + base_mask) >> base_shift);
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-    //=====================================================comp_op_rgba_contrast
-    template<class ColorT, class Order> struct comp_op_rgba_contrast
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        typedef typename color_type::long_type long_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            long_type dr = p[Order::R];
-            long_type dg = p[Order::G];
-            long_type db = p[Order::B];
-            int       da = p[Order::A];
-            long_type d2a = da >> 1;
-            unsigned s2a = sa >> 1;
-
-            int r = (int)((((dr - d2a) * int((sr - s2a)*2 + base_mask)) >> base_shift) + d2a); 
-            int g = (int)((((dg - d2a) * int((sg - s2a)*2 + base_mask)) >> base_shift) + d2a); 
-            int b = (int)((((db - d2a) * int((sb - s2a)*2 + base_mask)) >> base_shift) + d2a); 
-
-            r = (r < 0) ? 0 : r;
-            g = (g < 0) ? 0 : g;
-            b = (b < 0) ? 0 : b;
-
-            p[Order::R] = (value_type)((r > da) ? da : r);
-            p[Order::G] = (value_type)((g > da) ? da : g);
-            p[Order::B] = (value_type)((b > da) ? da : b);
-        }
-    };
-
-    //=====================================================comp_op_rgba_invert
-    template<class ColorT, class Order> 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<class ColorT, class Order> struct comp_op_rgba_invert_rgb
-    {
-        typedef ColorT color_type;
-        typedef Order order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        typedef typename color_type::long_type long_type;
-        enum base_scale_e
-        { 
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask
-        };
-
-        // Dca' = (Da - Dca) * Sca + Dca.(1 - Sa)
-        // Da'  = Sa + Da - Sa.Da 
-        static AGG_INLINE void blend_pix(value_type* p, 
-                                         unsigned sr, unsigned sg, unsigned sb, 
-                                         unsigned sa, unsigned cover)
-        {
-            if(cover < 255)
-            {
-                sr = (sr * cover + 255) >> 8;
-                sg = (sg * cover + 255) >> 8;
-                sb = (sb * cover + 255) >> 8;
-                sa = (sa * cover + 255) >> 8;
-            }
-            if(sa)
-            {
-                calc_type da = p[Order::A];
-                calc_type dr = ((da - p[Order::R]) * sr + base_mask) >> base_shift;
-                calc_type dg = ((da - p[Order::G]) * sg + base_mask) >> base_shift;
-                calc_type db = ((da - p[Order::B]) * sb + base_mask) >> base_shift;
-                calc_type s1a = base_mask - sa;
-                p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift));
-                p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift));
-                p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift));
-                p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
-            }
-        }
-    };
-
-
-
-
-
-    //======================================================comp_op_table_rgba
-    template<class ColorT, class Order> struct comp_op_table_rgba
-    {
-        typedef typename ColorT::value_type value_type;
-        typedef void (*comp_op_func_type)(value_type* p, 
-                                          unsigned cr, 
-                                          unsigned cg, 
-                                          unsigned cb,
-                                          unsigned ca,
-                                          unsigned cover);
-        static comp_op_func_type g_comp_op_func[];
-    };
-
-    //==========================================================g_comp_op_func
-    template<class ColorT, class Order> 
-    typename comp_op_table_rgba<ColorT, Order>::comp_op_func_type
-    comp_op_table_rgba<ColorT, Order>::g_comp_op_func[] = 
-    {
-        comp_op_rgba_clear      <ColorT,Order>::blend_pix,
-        comp_op_rgba_src        <ColorT,Order>::blend_pix,
-        comp_op_rgba_dst        <ColorT,Order>::blend_pix,
-        comp_op_rgba_src_over   <ColorT,Order>::blend_pix,
-        comp_op_rgba_dst_over   <ColorT,Order>::blend_pix,
-        comp_op_rgba_src_in     <ColorT,Order>::blend_pix,
-        comp_op_rgba_dst_in     <ColorT,Order>::blend_pix,
-        comp_op_rgba_src_out    <ColorT,Order>::blend_pix,
-        comp_op_rgba_dst_out    <ColorT,Order>::blend_pix,
-        comp_op_rgba_src_atop   <ColorT,Order>::blend_pix,
-        comp_op_rgba_dst_atop   <ColorT,Order>::blend_pix,
-        comp_op_rgba_xor        <ColorT,Order>::blend_pix,
-        comp_op_rgba_plus       <ColorT,Order>::blend_pix,
-        comp_op_rgba_minus      <ColorT,Order>::blend_pix,
-        comp_op_rgba_multiply   <ColorT,Order>::blend_pix,
-        comp_op_rgba_screen     <ColorT,Order>::blend_pix,
-        comp_op_rgba_overlay    <ColorT,Order>::blend_pix,
-        comp_op_rgba_darken     <ColorT,Order>::blend_pix,
-        comp_op_rgba_lighten    <ColorT,Order>::blend_pix,
-        comp_op_rgba_color_dodge<ColorT,Order>::blend_pix,
-        comp_op_rgba_color_burn <ColorT,Order>::blend_pix,
-        comp_op_rgba_hard_light <ColorT,Order>::blend_pix,
-        comp_op_rgba_soft_light <ColorT,Order>::blend_pix,
-        comp_op_rgba_difference <ColorT,Order>::blend_pix,
-        comp_op_rgba_exclusion  <ColorT,Order>::blend_pix,
-        comp_op_rgba_contrast   <ColorT,Order>::blend_pix,
-        comp_op_rgba_invert     <ColorT,Order>::blend_pix,
-        comp_op_rgba_invert_rgb <ColorT,Order>::blend_pix,
-        0
-    };
-
-
-    //==============================================================comp_op_e
-    enum comp_op_e
-    {
-        comp_op_clear,         //----comp_op_clear
-        comp_op_src,           //----comp_op_src
-        comp_op_dst,           //----comp_op_dst
-        comp_op_src_over,      //----comp_op_src_over
-        comp_op_dst_over,      //----comp_op_dst_over
-        comp_op_src_in,        //----comp_op_src_in
-        comp_op_dst_in,        //----comp_op_dst_in
-        comp_op_src_out,       //----comp_op_src_out
-        comp_op_dst_out,       //----comp_op_dst_out
-        comp_op_src_atop,      //----comp_op_src_atop
-        comp_op_dst_atop,      //----comp_op_dst_atop
-        comp_op_xor,           //----comp_op_xor
-        comp_op_plus,          //----comp_op_plus
-        comp_op_minus,         //----comp_op_minus
-        comp_op_multiply,      //----comp_op_multiply
-        comp_op_screen,        //----comp_op_screen
-        comp_op_overlay,       //----comp_op_overlay
-        comp_op_darken,        //----comp_op_darken
-        comp_op_lighten,       //----comp_op_lighten
-        comp_op_color_dodge,   //----comp_op_color_dodge
-        comp_op_color_burn,    //----comp_op_color_burn
-        comp_op_hard_light,    //----comp_op_hard_light
-        comp_op_soft_light,    //----comp_op_soft_light
-        comp_op_difference,    //----comp_op_difference
-        comp_op_exclusion,     //----comp_op_exclusion
-        comp_op_contrast,      //----comp_op_contrast
-        comp_op_invert,        //----comp_op_invert
-        comp_op_invert_rgb,    //----comp_op_invert_rgb
-
-        end_of_comp_op_e
-    };
-
-
-
-
-
-
-
-    //====================================================comp_op_adaptor_rgba
-    template<class ColorT, class Order> struct comp_op_adaptor_rgba
-    {
-        typedef Order  order_type;
-        typedef ColorT color_type;
-        typedef typename color_type::value_type value_type;
-        enum base_scale_e
-        {  
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask 
-        };
-
-        static AGG_INLINE void blend_pix(unsigned op, value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned ca,
-                                         unsigned cover)
-        {
-            comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op]
-                (p, (cr * ca + base_mask) >> base_shift, 
-                    (cg * ca + base_mask) >> base_shift,
-                    (cb * ca + base_mask) >> base_shift,
-                     ca, cover);
-        }
-    };
-
-    //=========================================comp_op_adaptor_clip_to_dst_rgba
-    template<class ColorT, class Order> struct comp_op_adaptor_clip_to_dst_rgba
-    {
-        typedef Order  order_type;
-        typedef ColorT color_type;
-        typedef typename color_type::value_type value_type;
-        enum base_scale_e
-        {  
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask 
-        };
-
-        static AGG_INLINE void blend_pix(unsigned op, value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned ca,
-                                         unsigned cover)
-        {
-            cr = (cr * ca + base_mask) >> base_shift;
-            cg = (cg * ca + base_mask) >> base_shift;
-            cb = (cb * ca + base_mask) >> base_shift;
-            unsigned da = p[Order::A];
-            comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op]
-                (p, (cr * da + base_mask) >> base_shift, 
-                    (cg * da + base_mask) >> base_shift, 
-                    (cb * da + base_mask) >> base_shift, 
-                    (ca * da + base_mask) >> base_shift, 
-                    cover);
-        }
-    };
-
-    //================================================comp_op_adaptor_rgba_pre
-    template<class ColorT, class Order> struct comp_op_adaptor_rgba_pre
-    {
-        typedef Order  order_type;
-        typedef ColorT color_type;
-        typedef typename color_type::value_type value_type;
-        enum base_scale_e
-        {  
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask 
-        };
-
-        static AGG_INLINE void blend_pix(unsigned op, value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned ca,
-                                         unsigned cover)
-        {
-            comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, cr, cg, cb, ca, cover);
-        }
-    };
-
-    //=====================================comp_op_adaptor_clip_to_dst_rgba_pre
-    template<class ColorT, class Order> struct comp_op_adaptor_clip_to_dst_rgba_pre
-    {
-        typedef Order  order_type;
-        typedef ColorT color_type;
-        typedef typename color_type::value_type value_type;
-        enum base_scale_e
-        {  
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask 
-        };
-
-        static AGG_INLINE void blend_pix(unsigned op, value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned ca,
-                                         unsigned cover)
-        {
-            unsigned da = p[Order::A];
-            comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op]
-                (p, (cr * da + base_mask) >> base_shift, 
-                    (cg * da + base_mask) >> base_shift, 
-                    (cb * da + base_mask) >> base_shift, 
-                    (ca * da + base_mask) >> base_shift, 
-                    cover);
-        }
-    };
-
-    //=======================================================comp_adaptor_rgba
-    template<class BlenderPre> struct comp_adaptor_rgba
-    {
-        typedef typename BlenderPre::order_type order_type;
-        typedef typename BlenderPre::color_type color_type;
-        typedef typename color_type::value_type value_type;
-        enum base_scale_e
-        {  
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask 
-        };
-
-        static AGG_INLINE void blend_pix(unsigned op, value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned ca,
-                                         unsigned cover)
-        {
-            BlenderPre::blend_pix(p, 
-                                  (cr * ca + base_mask) >> base_shift, 
-                                  (cg * ca + base_mask) >> base_shift,
-                                  (cb * ca + base_mask) >> base_shift,
-                                  ca, cover);
-        }
-    };
-
-    //==========================================comp_adaptor_clip_to_dst_rgba
-    template<class BlenderPre> struct comp_adaptor_clip_to_dst_rgba
-    {
-        typedef typename BlenderPre::order_type order_type;
-        typedef typename BlenderPre::color_type color_type;
-        typedef typename color_type::value_type value_type;
-        enum base_scale_e
-        {  
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask 
-        };
-
-        static AGG_INLINE void blend_pix(unsigned op, value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned ca,
-                                         unsigned cover)
-        {
-            cr = (cr * ca + base_mask) >> base_shift;
-            cg = (cg * ca + base_mask) >> base_shift;
-            cb = (cb * ca + base_mask) >> base_shift;
-            unsigned da = p[order_type::A];
-            BlenderPre::blend_pix(p, 
-                                  (cr * da + base_mask) >> base_shift, 
-                                  (cg * da + base_mask) >> base_shift, 
-                                  (cb * da + base_mask) >> base_shift, 
-                                  (ca * da + base_mask) >> base_shift, 
-                                  cover);
-        }
-    };
-
-    //======================================comp_adaptor_clip_to_dst_rgba_pre
-    template<class BlenderPre> struct comp_adaptor_clip_to_dst_rgba_pre
-    {
-        typedef typename BlenderPre::order_type order_type;
-        typedef typename BlenderPre::color_type color_type;
-        typedef typename color_type::value_type value_type;
-        enum base_scale_e
-        {  
-            base_shift = color_type::base_shift,
-            base_mask  = color_type::base_mask 
-        };
-
-        static AGG_INLINE void blend_pix(unsigned op, value_type* p, 
-                                         unsigned cr, unsigned cg, unsigned cb,
-                                         unsigned ca,
-                                         unsigned cover)
-        {
-            unsigned da = p[order_type::A];
-            BlenderPre::blend_pix(p, 
-                                  (cr * da + base_mask) >> base_shift, 
-                                  (cg * da + base_mask) >> base_shift, 
-                                  (cb * da + base_mask) >> base_shift, 
-                                  (ca * da + base_mask) >> base_shift, 
-                                  cover);
-        }
-    };
-
-
-
-
-
-
-    //===============================================copy_or_blend_rgba_wrapper
-    template<class Blender> struct copy_or_blend_rgba_wrapper
-    {
-        typedef typename Blender::color_type color_type;
-        typedef typename Blender::order_type order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        {
-            base_shift = color_type::base_shift,
-            base_scale = color_type::base_scale,
-            base_mask  = color_type::base_mask
-        };
-
-        //--------------------------------------------------------------------
-        static AGG_INLINE void copy_or_blend_pix(value_type* p, 
-                                                 unsigned cr, unsigned cg, unsigned cb,
-                                                 unsigned alpha)
-        {
-            if(alpha)
-            {
-                if(alpha == base_mask)
-                {
-                    p[order_type::R] = cr;
-                    p[order_type::G] = cg;
-                    p[order_type::B] = cb;
-                    p[order_type::A] = base_mask;
-                }
-                else
-                {
-                    Blender::blend_pix(p, cr, cg, cb, alpha);
-                }
-            }
-        }
-
-        //--------------------------------------------------------------------
-        static AGG_INLINE void copy_or_blend_pix(value_type* p, 
-                                                 unsigned cr, unsigned cg, unsigned cb,
-                                                 unsigned alpha,
-                                                 unsigned cover)
-        {
-            if(cover == 255)
-            {
-                copy_or_blend_pix(p, cr, cg, cb, alpha);
-            }
-            else
-            {
-                if(alpha)
-                {
-                    alpha = (alpha * (cover + 1)) >> 8;
-                    if(alpha == base_mask)
-                    {
-                        p[order_type::R] = cr;
-                        p[order_type::G] = cg;
-                        p[order_type::B] = cb;
-                        p[order_type::A] = base_mask;
-                    }
-                    else
-                    {
-                        Blender::blend_pix(p, cr, cg, cb, alpha, cover);
-                    }
-                }
-            }
-        }
-    };
-
-
-
-
-
-    
-    //=================================================pixfmt_alpha_blend_rgba
-    template<class Blender, class RenBuf, class PixelT = int32u> 
-    class pixfmt_alpha_blend_rgba
-    {
-    public:
-        typedef RenBuf   rbuf_type;
-        typedef typename rbuf_type::row_data row_data;
-        typedef PixelT   pixel_type;
-        typedef Blender  blender_type;
-        typedef typename blender_type::color_type color_type;
-        typedef typename blender_type::order_type order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        typedef copy_or_blend_rgba_wrapper<blender_type> cob_type;
-        enum base_scale_e
-        {
-            base_shift = color_type::base_shift,
-            base_scale = color_type::base_scale,
-            base_mask  = color_type::base_mask,
-            pix_width  = sizeof(pixel_type)
-        };
-
-        //--------------------------------------------------------------------
-        pixfmt_alpha_blend_rgba() : m_rbuf(0) {}
-        explicit pixfmt_alpha_blend_rgba(rbuf_type& rb) : m_rbuf(&rb) {}
-        void attach(rbuf_type& rb) { m_rbuf = &rb; }
-
-        //--------------------------------------------------------------------
-        template<class PixFmt>
-        bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
-        {
-            rect_i r(x1, y1, x2, y2);
-            if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
-            {
-                int stride = pixf.stride();
-                m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), 
-                               (r.x2 - r.x1) + 1,
-                               (r.y2 - r.y1) + 1,
-                               stride);
-                return true;
-            }
-            return false;
-        }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE unsigned width()  const { return m_rbuf->width();  }
-        AGG_INLINE unsigned height() const { return m_rbuf->height(); }
-        AGG_INLINE int      stride() const { return m_rbuf->stride(); }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE       int8u* row_ptr(int y)       { return m_rbuf->row_ptr(y); }
-        AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
-        AGG_INLINE row_data     row(int y)     const { return m_rbuf->row(y); }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE int8u* pix_ptr(int x, int y)
-        {
-            return m_rbuf->row_ptr(y) + x * pix_width;
-        }
-
-        AGG_INLINE const int8u* pix_ptr(int x, int y) const
-        {
-            return m_rbuf->row_ptr(y) + x * pix_width;
-        }
-
-
-        //--------------------------------------------------------------------
-        AGG_INLINE static void make_pix(int8u* p, const color_type& c)
-        {
-            ((value_type*)p)[order_type::R] = c.r;
-            ((value_type*)p)[order_type::G] = c.g;
-            ((value_type*)p)[order_type::B] = c.b;
-            ((value_type*)p)[order_type::A] = c.a;
-        }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE color_type pixel(int x, int y) const
-        {
-            const value_type* p = (const value_type*)m_rbuf->row_ptr(y);
-            if(p)
-            {
-                p += x << 2;
-                return color_type(p[order_type::R], 
-                                  p[order_type::G], 
-                                  p[order_type::B], 
-                                  p[order_type::A]);
-            }
-            return color_type::no_color();
-        }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
-        {
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2);
-            p[order_type::R] = c.r;
-            p[order_type::G] = c.g;
-            p[order_type::B] = c.b;
-            p[order_type::A] = c.a;
-        }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
-        {
-            cob_type::copy_or_blend_pix(
-                (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2), 
-                c.r, c.g, c.b, c.a, 
-                cover);
-        }
-
-
-        //--------------------------------------------------------------------
-        AGG_INLINE void copy_hline(int x, int y, 
-                                   unsigned len, 
-                                   const color_type& c)
-        {
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
-            pixel_type v;
-            ((value_type*)&v)[order_type::R] = c.r;
-            ((value_type*)&v)[order_type::G] = c.g;
-            ((value_type*)&v)[order_type::B] = c.b;
-            ((value_type*)&v)[order_type::A] = c.a;
-            do
-            {
-                *(pixel_type*)p = v;
-                p += 4;
-            }
-            while(--len);
-        }
-
-
-        //--------------------------------------------------------------------
-        AGG_INLINE void copy_vline(int x, int y,
-                                   unsigned len, 
-                                   const color_type& c)
-        {
-            pixel_type v;
-            ((value_type*)&v)[order_type::R] = c.r;
-            ((value_type*)&v)[order_type::G] = c.g;
-            ((value_type*)&v)[order_type::B] = c.b;
-            ((value_type*)&v)[order_type::A] = c.a;
-            do
-            {
-                value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                *(pixel_type*)p = v;
-            }
-            while(--len);
-        }
-
-
-        //--------------------------------------------------------------------
-        void blend_hline(int x, int y,
-                         unsigned len, 
-                         const color_type& c,
-                         int8u cover)
-        {
-            if (c.a)
-            {
-                value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
-                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
-                if(alpha == base_mask)
-                {
-                    pixel_type v;
-                    ((value_type*)&v)[order_type::R] = c.r;
-                    ((value_type*)&v)[order_type::G] = c.g;
-                    ((value_type*)&v)[order_type::B] = c.b;
-                    ((value_type*)&v)[order_type::A] = c.a;
-                    do
-                    {
-                        *(pixel_type*)p = v;
-                        p += 4;
-                    }
-                    while(--len);
-                }
-                else
-                {
-                    if(cover == 255)
-                    {
-                        do
-                        {
-                            blender_type::blend_pix(p, c.r, c.g, c.b, alpha);
-                            p += 4;
-                        }
-                        while(--len);
-                    }
-                    else
-                    {
-                        do
-                        {
-                            blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover);
-                            p += 4;
-                        }
-                        while(--len);
-                    }
-                }
-            }
-        }
-
-
-        //--------------------------------------------------------------------
-        void blend_vline(int x, int y,
-                         unsigned len, 
-                         const color_type& c,
-                         int8u cover)
-        {
-            if (c.a)
-            {
-                value_type* p;
-                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
-                if(alpha == base_mask)
-                {
-                    pixel_type v;
-                    ((value_type*)&v)[order_type::R] = c.r;
-                    ((value_type*)&v)[order_type::G] = c.g;
-                    ((value_type*)&v)[order_type::B] = c.b;
-                    ((value_type*)&v)[order_type::A] = c.a;
-                    do
-                    {
-                        p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                        *(pixel_type*)p = v;
-                    }
-                    while(--len);
-                }
-                else
-                {
-                    if(cover == 255)
-                    {
-                        do
-                        {
-                            p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                            blender_type::blend_pix(p, c.r, c.g, c.b, alpha);
-                        }
-                        while(--len);
-                    }
-                    else
-                    {
-                        do
-                        {
-                            p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                            blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover);
-                        }
-                        while(--len);
-                    }
-                }
-            }
-        }
-
-
-        //--------------------------------------------------------------------
-        void blend_solid_hspan(int x, int y,
-                               unsigned len, 
-                               const color_type& c,
-                               const int8u* covers)
-        {
-            if (c.a)
-            {
-                value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
-                do 
-                {
-                    calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
-                    if(alpha == base_mask)
-                    {
-                        p[order_type::R] = c.r;
-                        p[order_type::G] = c.g;
-                        p[order_type::B] = c.b;
-                        p[order_type::A] = base_mask;
-                    }
-                    else
-                    {
-                        blender_type::blend_pix(p, c.r, c.g, c.b, alpha, *covers);
-                    }
-                    p += 4;
-                    ++covers;
-                }
-                while(--len);
-            }
-        }
-
-
-        //--------------------------------------------------------------------
-        void blend_solid_vspan(int x, int y,
-                               unsigned len, 
-                               const color_type& c,
-                               const int8u* covers)
-        {
-            if (c.a)
-            {
-                do 
-                {
-                    value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                    calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
-                    if(alpha == base_mask)
-                    {
-                        p[order_type::R] = c.r;
-                        p[order_type::G] = c.g;
-                        p[order_type::B] = c.b;
-                        p[order_type::A] = base_mask;
-                    }
-                    else
-                    {
-                        blender_type::blend_pix(p, c.r, c.g, c.b, alpha, *covers);
-                    }
-                    ++covers;
-                }
-                while(--len);
-            }
-        }
-
-
-        //--------------------------------------------------------------------
-        void copy_color_hspan(int x, int y,
-                              unsigned len, 
-                              const color_type* colors)
-        {
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
-            do 
-            {
-                p[order_type::R] = colors->r;
-                p[order_type::G] = colors->g;
-                p[order_type::B] = colors->b;
-                p[order_type::A] = colors->a;
-                ++colors;
-                p += 4;
-            }
-            while(--len);
-        }
-
-
-        //--------------------------------------------------------------------
-        void copy_color_vspan(int x, int y,
-                              unsigned len, 
-                              const color_type* colors)
-        {
-            do 
-            {
-                value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                p[order_type::R] = colors->r;
-                p[order_type::G] = colors->g;
-                p[order_type::B] = colors->b;
-                p[order_type::A] = colors->a;
-                ++colors;
-            }
-            while(--len);
-        }
-
-
-        //--------------------------------------------------------------------
-        void blend_color_hspan(int x, int y,
-                               unsigned len, 
-                               const color_type* colors,
-                               const int8u* covers,
-                               int8u cover)
-        {
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
-            if(covers)
-            {
-                do 
-                {
-                    cob_type::copy_or_blend_pix(p, 
-                                                colors->r, 
-                                                colors->g, 
-                                                colors->b, 
-                                                colors->a, 
-                                                *covers++);
-                    p += 4;
-                    ++colors;
-                }
-                while(--len);
-            }
-            else
-            {
-                if(cover == 255)
-                {
-                    do 
-                    {
-                        cob_type::copy_or_blend_pix(p, 
-                                                    colors->r, 
-                                                    colors->g, 
-                                                    colors->b, 
-                                                    colors->a);
-                        p += 4;
-                        ++colors;
-                    }
-                    while(--len);
-                }
-                else
-                {
-                    do 
-                    {
-                        cob_type::copy_or_blend_pix(p, 
-                                                    colors->r, 
-                                                    colors->g, 
-                                                    colors->b, 
-                                                    colors->a, 
-                                                    cover);
-                        p += 4;
-                        ++colors;
-                    }
-                    while(--len);
-                }
-            }
-        }
-
-
-
-        //--------------------------------------------------------------------
-        void blend_color_vspan(int x, int y,
-                               unsigned len, 
-                               const color_type* colors,
-                               const int8u* covers,
-                               int8u cover)
-        {
-            value_type* p;
-            if(covers)
-            {
-                do 
-                {
-                    p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                    cob_type::copy_or_blend_pix(p, 
-                                                colors->r, 
-                                                colors->g, 
-                                                colors->b, 
-                                                colors->a,
-                                                *covers++);
-                    ++colors;
-                }
-                while(--len);
-            }
-            else
-            {
-                if(cover == 255)
-                {
-                    do 
-                    {
-                        p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                        cob_type::copy_or_blend_pix(p, 
-                                                    colors->r, 
-                                                    colors->g, 
-                                                    colors->b, 
-                                                    colors->a);
-                        ++colors;
-                    }
-                    while(--len);
-                }
-                else
-                {
-                    do 
-                    {
-                        p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                        cob_type::copy_or_blend_pix(p, 
-                                                    colors->r, 
-                                                    colors->g, 
-                                                    colors->b, 
-                                                    colors->a, 
-                                                    cover);
-                        ++colors;
-                    }
-                    while(--len);
-                }
-            }
-        }
-
-        //--------------------------------------------------------------------
-        template<class Function> void for_each_pixel(Function f)
-        {
-            unsigned y;
-            for(y = 0; y < height(); ++y)
-            {
-                row_data r = m_rbuf->row(y);
-                if(r.ptr)
-                {
-                    unsigned len = r.x2 - r.x1 + 1;
-                    value_type* p = 
-                        (value_type*)m_rbuf->row_ptr(r.x1, y, len) + (r.x1 << 2);
-                    do
-                    {
-                        f(p);
-                        p += 4;
-                    }
-                    while(--len);
-                }
-            }
-        }
-
-        //--------------------------------------------------------------------
-        void premultiply()
-        {
-            for_each_pixel(multiplier_rgba<color_type, order_type>::premultiply);
-        }
-
-        //--------------------------------------------------------------------
-        void demultiply()
-        {
-            for_each_pixel(multiplier_rgba<color_type, order_type>::demultiply);
-        }
-
-        //--------------------------------------------------------------------
-        template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
-        {
-            for_each_pixel(apply_gamma_dir_rgba<color_type, order_type, GammaLut>(g));
-        }
-
-        //--------------------------------------------------------------------
-        template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
-        {
-            for_each_pixel(apply_gamma_inv_rgba<color_type, order_type, GammaLut>(g));
-        }
-
-        //--------------------------------------------------------------------
-        template<class RenBuf2> void copy_from(const RenBuf2& from, 
-                                               int xdst, int ydst,
-                                               int xsrc, int ysrc,
-                                               unsigned len)
-        {
-            const int8u* p = from.row_ptr(ysrc);
-            if(p)
-            {
-                memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, 
-                        p + xsrc * pix_width, 
-                        len * pix_width);
-            }
-        }
-
-        //--------------------------------------------------------------------
-        template<class SrcPixelFormatRenderer>
-        void blend_from(const SrcPixelFormatRenderer& from, 
-                        int xdst, int ydst,
-                        int xsrc, int ysrc,
-                        unsigned len,
-                        int8u cover)
-        {
-            typedef typename SrcPixelFormatRenderer::order_type src_order;
-            const value_type* psrc = (value_type*)from.row_ptr(ysrc);
-            if(psrc)
-            {
-                psrc += xsrc << 2;
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
-                int incp = 4;
-                if(xdst > xsrc)
-                {
-                    psrc += (len-1) << 2;
-                    pdst += (len-1) << 2;
-                    incp = -4;
-                }
-
-                if(cover == 255)
-                {
-                    do 
-                    {
-                        cob_type::copy_or_blend_pix(pdst, 
-                                                    psrc[src_order::R],
-                                                    psrc[src_order::G],
-                                                    psrc[src_order::B],
-                                                    psrc[src_order::A]);
-                        psrc += incp;
-                        pdst += incp;
-                    }
-                    while(--len);
-                }
-                else
-                {
-                    do 
-                    {
-                        cob_type::copy_or_blend_pix(pdst, 
-                                                    psrc[src_order::R],
-                                                    psrc[src_order::G],
-                                                    psrc[src_order::B],
-                                                    psrc[src_order::A],
-                                                    cover);
-                        psrc += incp;
-                        pdst += incp;
-                    }
-                    while(--len);
-                }
-            }
-        }
-
-        //--------------------------------------------------------------------
-        template<class SrcPixelFormatRenderer>
-        void blend_from_color(const SrcPixelFormatRenderer& from, 
-                              const color_type& color,
-                              int xdst, int ydst,
-                              int xsrc, int ysrc,
-                              unsigned len,
-                              int8u cover)
-        {
-            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
-            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
-            if(psrc)
-            {
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
-                do 
-                {
-                    cob_type::copy_or_blend_pix(pdst, 
-                                                color.r, color.g, color.b, color.a,
-                                                (*psrc * cover + base_mask) >> base_shift);
-                    ++psrc;
-                    pdst += 4;
-                }
-                while(--len);
-            }
-        }
-
-        //--------------------------------------------------------------------
-        template<class SrcPixelFormatRenderer>
-        void blend_from_lut(const SrcPixelFormatRenderer& from, 
-                            const color_type* color_lut,
-                            int xdst, int ydst,
-                            int xsrc, int ysrc,
-                            unsigned len,
-                            int8u cover)
-        {
-            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
-            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
-            if(psrc)
-            {
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
-
-                if(cover == 255)
-                {
-                    do 
-                    {
-                        const color_type& color = color_lut[*psrc];
-                        cob_type::copy_or_blend_pix(pdst, 
-                                                    color.r, color.g, color.b, color.a);
-                        ++psrc;
-                        pdst += 4;
-                    }
-                    while(--len);
-                }
-                else
-                {
-                    do 
-                    {
-                        const color_type& color = color_lut[*psrc];
-                        cob_type::copy_or_blend_pix(pdst, 
-                                                    color.r, color.g, color.b, color.a,
-                                                    cover);
-                        ++psrc;
-                        pdst += 4;
-                    }
-                    while(--len);
-                }
-            }
-        }
-
-    private:
-        rbuf_type* m_rbuf;
-    };
-
-
-
-
-    //================================================pixfmt_custom_blend_rgba
-    template<class Blender, class RenBuf> class pixfmt_custom_blend_rgba
-    {
-    public:
-        typedef RenBuf   rbuf_type;
-        typedef typename rbuf_type::row_data row_data;
-        typedef Blender  blender_type;
-        typedef typename blender_type::color_type color_type;
-        typedef typename blender_type::order_type order_type;
-        typedef typename color_type::value_type value_type;
-        typedef typename color_type::calc_type calc_type;
-        enum base_scale_e
-        {
-            base_shift = color_type::base_shift,
-            base_scale = color_type::base_scale,
-            base_mask  = color_type::base_mask,
-            pix_width  = sizeof(value_type) * 4 
-        };
-
-
-        //--------------------------------------------------------------------
-        pixfmt_custom_blend_rgba() : m_rbuf(0), m_comp_op(3) {}
-        explicit pixfmt_custom_blend_rgba(rbuf_type& rb, unsigned comp_op=3) : 
-            m_rbuf(&rb),
-            m_comp_op(comp_op)
-        {}
-        void attach(rbuf_type& rb) { m_rbuf = &rb; }
-
-        //--------------------------------------------------------------------
-        template<class PixFmt>
-        bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
-        {
-            rect_i r(x1, y1, x2, y2);
-            if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
-            {
-                int stride = pixf.stride();
-                m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), 
-                               (r.x2 - r.x1) + 1,
-                               (r.y2 - r.y1) + 1,
-                               stride);
-                return true;
-            }
-            return false;
-        }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE unsigned width()  const { return m_rbuf->width();  }
-        AGG_INLINE unsigned height() const { return m_rbuf->height(); }
-        AGG_INLINE int      stride() const { return m_rbuf->stride(); }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE       int8u* row_ptr(int y)       { return m_rbuf->row_ptr(y); }
-        AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
-        AGG_INLINE row_data     row(int y)     const { return m_rbuf->row(y); }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE int8u* pix_ptr(int x, int y)
-        {
-            return m_rbuf->row_ptr(y) + x * pix_width;
-        }
-
-        AGG_INLINE const int8u* pix_ptr(int x, int y) const
-        {
-            return m_rbuf->row_ptr(y) + x * pix_width;
-        }
-
-        //--------------------------------------------------------------------
-        void comp_op(unsigned op) { m_comp_op = op; }
-        unsigned comp_op() const  { return m_comp_op; }
-
-        //--------------------------------------------------------------------
-        AGG_INLINE static void make_pix(int8u* p, const color_type& c)
-        {
-            ((value_type*)p)[order_type::R] = c.r;
-            ((value_type*)p)[order_type::G] = c.g;
-            ((value_type*)p)[order_type::B] = c.b;
-            ((value_type*)p)[order_type::A] = c.a;
-        }
-
-        //--------------------------------------------------------------------
-        color_type pixel(int x, int y) const
-        {
-            const value_type* p = (value_type*)m_rbuf->row_ptr(y) + (x << 2);
-            return color_type(p[order_type::R], 
-                              p[order_type::G], 
-                              p[order_type::B], 
-                              p[order_type::A]);
-        }
-
-        //--------------------------------------------------------------------
-        void copy_pixel(int x, int y, const color_type& c)
-        {
-            blender_type::blend_pix(
-                m_comp_op, 
-                (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2), 
-                c.r, c.g, c.b, c.a, 255);
-        }
-
-        //--------------------------------------------------------------------
-        void blend_pixel(int x, int y, const color_type& c, int8u cover)
-        {
-            blender_type::blend_pix(
-                m_comp_op, 
-                (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2),
-                c.r, c.g, c.b, c.a, 
-                cover);
-        }
-
-        //--------------------------------------------------------------------
-        void copy_hline(int x, int y, unsigned len, const color_type& c)
-        {
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);;
-            do
-            {
-                blender_type::blend_pix(m_comp_op, p, c.r, c.g, c.b, c.a, 255);
-                p += 4;
-            }
-            while(--len);
-        }
-
-        //--------------------------------------------------------------------
-        void copy_vline(int x, int y, unsigned len, const color_type& c)
-        {
-            do
-            {
-                blender_type::blend_pix(
-                    m_comp_op, 
-                    (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2),
-                    c.r, c.g, c.b, c.a, 255);
-            }
-            while(--len);
-        }
-
-        //--------------------------------------------------------------------
-        void blend_hline(int x, int y, unsigned len, 
-                         const color_type& c, int8u cover)
-        {
-
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
-            do
-            {
-                blender_type::blend_pix(m_comp_op, p, c.r, c.g, c.b, c.a, cover);
-                p += 4;
-            }
-            while(--len);
-        }
-
-        //--------------------------------------------------------------------
-        void blend_vline(int x, int y, unsigned len, 
-                         const color_type& c, int8u cover)
-        {
-
-            do
-            {
-                blender_type::blend_pix(
-                    m_comp_op, 
-                    (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), 
-                    c.r, c.g, c.b, c.a, 
-                    cover);
-            }
-            while(--len);
-        }
-
-        //--------------------------------------------------------------------
-        void blend_solid_hspan(int x, int y, unsigned len, 
-                               const color_type& c, const int8u* covers)
-        {
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
-            do 
-            {
-                blender_type::blend_pix(m_comp_op, 
-                                        p, c.r, c.g, c.b, c.a, 
-                                        *covers++);
-                p += 4;
-            }
-            while(--len);
-        }
-
-        //--------------------------------------------------------------------
-        void blend_solid_vspan(int x, int y, unsigned len, 
-                               const color_type& c, const int8u* covers)
-        {
-            do 
-            {
-                blender_type::blend_pix(
-                    m_comp_op, 
-                    (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), 
-                    c.r, c.g, c.b, c.a, 
-                    *covers++);
-            }
-            while(--len);
-        }
-
-        //--------------------------------------------------------------------
-        void copy_color_hspan(int x, int y,
-                              unsigned len, 
-                              const color_type* colors)
-        {
-
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
-            do 
-            {
-                p[order_type::R] = colors->r;
-                p[order_type::G] = colors->g;
-                p[order_type::B] = colors->b;
-                p[order_type::A] = colors->a;
-                ++colors;
-                p += 4;
-            }
-            while(--len);
-        }
-
-        //--------------------------------------------------------------------
-        void copy_color_vspan(int x, int y,
-                              unsigned len, 
-                              const color_type* colors)
-        {
-            do 
-            {
-                value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
-                p[order_type::R] = colors->r;
-                p[order_type::G] = colors->g;
-                p[order_type::B] = colors->b;
-                p[order_type::A] = colors->a;
-                ++colors;
-            }
-            while(--len);
-        }
-
-        //--------------------------------------------------------------------
-        void blend_color_hspan(int x, int y, unsigned len, 
-                               const color_type* colors, 
-                               const int8u* covers,
-                               int8u cover)
-        {
-            value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
-            do 
-            {
-                blender_type::blend_pix(m_comp_op, 
-                                        p, 
-                                        colors->r, 
-                                        colors->g, 
-                                        colors->b, 
-                                        colors->a, 
-                                        covers ? *covers++ : cover);
-                p += 4;
-                ++colors;
-            }
-            while(--len);
-        }
-
-        //--------------------------------------------------------------------
-        void blend_color_vspan(int x, int y, unsigned len, 
-                               const color_type* colors, 
-                               const int8u* covers,
-                               int8u cover)
-        {
-            do 
-            {
-                blender_type::blend_pix(
-                    m_comp_op, 
-                    (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), 
-                    colors->r,
-                    colors->g,
-                    colors->b,
-                    colors->a,
-                    covers ? *covers++ : cover);
-                ++colors;
-            }
-            while(--len);
-
-        }
-
-        //--------------------------------------------------------------------
-        template<class Function> void for_each_pixel(Function f)
-        {
-            unsigned y;
-            for(y = 0; y < height(); ++y)
-            {
-                row_data r = m_rbuf->row(y);
-                if(r.ptr)
-                {
-                    unsigned len = r.x2 - r.x1 + 1;
-                    value_type* p = 
-                        (value_type*)m_rbuf->row_ptr(r.x1, y, len) + (r.x1 << 2);
-                    do
-                    {
-                        f(p);
-                        p += 4;
-                    }
-                    while(--len);
-                }
-            }
-        }
-
-        //--------------------------------------------------------------------
-        void premultiply()
-        {
-            for_each_pixel(multiplier_rgba<color_type, order_type>::premultiply);
-        }
-
-        //--------------------------------------------------------------------
-        void demultiply()
-        {
-            for_each_pixel(multiplier_rgba<color_type, order_type>::demultiply);
-        }
-
-        //--------------------------------------------------------------------
-        template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
-        {
-            for_each_pixel(apply_gamma_dir_rgba<color_type, order_type, GammaLut>(g));
-        }
-
-        //--------------------------------------------------------------------
-        template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
-        {
-            for_each_pixel(apply_gamma_inv_rgba<color_type, order_type, GammaLut>(g));
-        }
-
-        //--------------------------------------------------------------------
-        template<class RenBuf2> void copy_from(const RenBuf2& from, 
-                                               int xdst, int ydst,
-                                               int xsrc, int ysrc,
-                                               unsigned len)
-        {
-            const int8u* p = from.row_ptr(ysrc);
-            if(p)
-            {
-                memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, 
-                        p + xsrc * pix_width, 
-                        len * pix_width);
-            }
-        }
-
-        //--------------------------------------------------------------------
-        template<class SrcPixelFormatRenderer> 
-        void blend_from(const SrcPixelFormatRenderer& from, 
-                        int xdst, int ydst,
-                        int xsrc, int ysrc,
-                        unsigned len,
-                        int8u cover)
-        {
-            typedef typename SrcPixelFormatRenderer::order_type src_order;
-            const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
-            if(psrc)
-            {
-                psrc += xsrc << 2;
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
-
-                int incp = 4;
-                if(xdst > xsrc)
-                {
-                    psrc += (len-1) << 2;
-                    pdst += (len-1) << 2;
-                    incp = -4;
-                }
-
-                do 
-                {
-                    blender_type::blend_pix(m_comp_op, 
-                                            pdst, 
-                                            psrc[src_order::R],
-                                            psrc[src_order::G],
-                                            psrc[src_order::B],
-                                            psrc[src_order::A],
-                                            cover);
-                    psrc += incp;
-                    pdst += incp;
-                }
-                while(--len);
-            }
-        }
-
-        //--------------------------------------------------------------------
-        template<class SrcPixelFormatRenderer>
-        void blend_from_color(const SrcPixelFormatRenderer& from, 
-                              const color_type& color,
-                              int xdst, int ydst,
-                              int xsrc, int ysrc,
-                              unsigned len,
-                              int8u cover)
-        {
-            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
-            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
-            if(psrc)
-            {
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
-                do 
-                {
-                    blender_type::blend_pix(m_comp_op,
-                                            pdst, 
-                                            color.r, color.g, color.b, color.a,
-                                            (*psrc * cover + base_mask) >> base_shift);
-                    ++psrc;
-                    pdst += 4;
-                }
-                while(--len);
-            }
-        }
-
-        //--------------------------------------------------------------------
-        template<class SrcPixelFormatRenderer>
-        void blend_from_lut(const SrcPixelFormatRenderer& from, 
-                            const color_type* color_lut,
-                            int xdst, int ydst,
-                            int xsrc, int ysrc,
-                            unsigned len,
-                            int8u cover)
-        {
-            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
-            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
-            if(psrc)
-            {
-                value_type* pdst = 
-                    (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
-                do 
-                {
-                    const color_type& color = color_lut[*psrc];
-                    blender_type::blend_pix(m_comp_op,
-                                            pdst, 
-                                            color.r, color.g, color.b, color.a,
-                                            cover);
-                    ++psrc;
-                    pdst += 4;
-                }
-                while(--len);
-            }
-        }
-
-    private:
-        rbuf_type* m_rbuf;
-        unsigned m_comp_op;
-    };
-
-
-
-
-    //-----------------------------------------------------------------------
-    typedef blender_rgba<rgba8, order_rgba> blender_rgba32; //----blender_rgba32
-    typedef blender_rgba<rgba8, order_argb> blender_argb32; //----blender_argb32
-    typedef blender_rgba<rgba8, order_abgr> blender_abgr32; //----blender_abgr32
-    typedef blender_rgba<rgba8, order_bgra> blender_bgra32; //----blender_bgra32
-
-    typedef blender_rgba_pre<rgba8, order_rgba> blender_rgba32_pre; //----blender_rgba32_pre
-    typedef blender_rgba_pre<rgba8, order_argb> blender_argb32_pre; //----blender_argb32_pre
-    typedef blender_rgba_pre<rgba8, order_abgr> blender_abgr32_pre; //----blender_abgr32_pre
-    typedef blender_rgba_pre<rgba8, order_bgra> blender_bgra32_pre; //----blender_bgra32_pre
-
-    typedef blender_rgba_plain<rgba8, order_rgba> blender_rgba32_plain; //----blender_rgba32_plain
-    typedef blender_rgba_plain<rgba8, order_argb> blender_argb32_plain; //----blender_argb32_plain
-    typedef blender_rgba_plain<rgba8, order_abgr> blender_abgr32_plain; //----blender_abgr32_plain
-    typedef blender_rgba_plain<rgba8, order_bgra> blender_bgra32_plain; //----blender_bgra32_plain
-
-    typedef blender_rgba<rgba16, order_rgba> blender_rgba64; //----blender_rgba64
-    typedef blender_rgba<rgba16, order_argb> blender_argb64; //----blender_argb64
-    typedef blender_rgba<rgba16, order_abgr> blender_abgr64; //----blender_abgr64
-    typedef blender_rgba<rgba16, order_bgra> blender_bgra64; //----blender_bgra64
-
-    typedef blender_rgba_pre<rgba16, order_rgba> blender_rgba64_pre; //----blender_rgba64_pre
-    typedef blender_rgba_pre<rgba16, order_argb> blender_argb64_pre; //----blender_argb64_pre
-    typedef blender_rgba_pre<rgba16, order_abgr> blender_abgr64_pre; //----blender_abgr64_pre
-    typedef blender_rgba_pre<rgba16, order_bgra> blender_bgra64_pre; //----blender_bgra64_pre
-
-
-    //-----------------------------------------------------------------------
-    typedef int32u pixel32_type;
-    typedef pixfmt_alpha_blend_rgba<blender_rgba32, rendering_buffer, pixel32_type> pixfmt_rgba32; //----pixfmt_rgba32
-    typedef pixfmt_alpha_blend_rgba<blender_argb32, rendering_buffer, pixel32_type> pixfmt_argb32; //----pixfmt_argb32
-    typedef pixfmt_alpha_blend_rgba<blender_abgr32, rendering_buffer, pixel32_type> pixfmt_abgr32; //----pixfmt_abgr32
-    typedef pixfmt_alpha_blend_rgba<blender_bgra32, rendering_buffer, pixel32_type> pixfmt_bgra32; //----pixfmt_bgra32
-
-    typedef pixfmt_alpha_blend_rgba<blender_rgba32_pre, rendering_buffer, pixel32_type> pixfmt_rgba32_pre; //----pixfmt_rgba32_pre
-    typedef pixfmt_alpha_blend_rgba<blender_argb32_pre, rendering_buffer, pixel32_type> pixfmt_argb32_pre; //----pixfmt_argb32_pre
-    typedef pixfmt_alpha_blend_rgba<blender_abgr32_pre, rendering_buffer, pixel32_type> pixfmt_abgr32_pre; //----pixfmt_abgr32_pre
-    typedef pixfmt_alpha_blend_rgba<blender_bgra32_pre, rendering_buffer, pixel32_type> pixfmt_bgra32_pre; //----pixfmt_bgra32_pre
-
-    typedef pixfmt_alpha_blend_rgba<blender_rgba32_plain, rendering_buffer, pixel32_type> pixfmt_rgba32_plain; //----pixfmt_rgba32_plain
-    typedef pixfmt_alpha_blend_rgba<blender_argb32_plain, rendering_buffer, pixel32_type> pixfmt_argb32_plain; //----pixfmt_argb32_plain
-    typedef pixfmt_alpha_blend_rgba<blender_abgr32_plain, rendering_buffer, pixel32_type> pixfmt_abgr32_plain; //----pixfmt_abgr32_plain
-    typedef pixfmt_alpha_blend_rgba<blender_bgra32_plain, rendering_buffer, pixel32_type> pixfmt_bgra32_plain; //----pixfmt_bgra32_plain
-
-    struct  pixel64_type { int16u c[4]; };
-    typedef pixfmt_alpha_blend_rgba<blender_rgba64, rendering_buffer, pixel64_type> pixfmt_rgba64; //----pixfmt_rgba64
-    typedef pixfmt_alpha_blend_rgba<blender_argb64, rendering_buffer, pixel64_type> pixfmt_argb64; //----pixfmt_argb64
-    typedef pixfmt_alpha_blend_rgba<blender_abgr64, rendering_buffer, pixel64_type> pixfmt_abgr64; //----pixfmt_abgr64
-    typedef pixfmt_alpha_blend_rgba<blender_bgra64, rendering_buffer, pixel64_type> pixfmt_bgra64; //----pixfmt_bgra64
-
-    typedef pixfmt_alpha_blend_rgba<blender_rgba64_pre, rendering_buffer, pixel64_type> pixfmt_rgba64_pre; //----pixfmt_rgba64_pre
-    typedef pixfmt_alpha_blend_rgba<blender_argb64_pre, rendering_buffer, pixel64_type> pixfmt_argb64_pre; //----pixfmt_argb64_pre
-    typedef pixfmt_alpha_blend_rgba<blender_abgr64_pre, rendering_buffer, pixel64_type> pixfmt_abgr64_pre; //----pixfmt_abgr64_pre
-    typedef pixfmt_alpha_blend_rgba<blender_bgra64_pre, rendering_buffer, pixel64_type> pixfmt_bgra64_pre; //----pixfmt_bgra64_pre
-}
-
-#endif
-
diff --git a/src/agg/agg_rasterizer_cells_aa.h b/src/agg/agg_rasterizer_cells_aa.h
index d3bb1387c..1147148fa 100644
--- a/src/agg/agg_rasterizer_cells_aa.h
+++ b/src/agg/agg_rasterizer_cells_aa.h
@@ -1,25 +1,12 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
 //----------------------------------------------------------------------------
 //
 // The author gratefully acknowleges the support of David Turner, 
@@ -27,6 +14,10 @@
 // libray - in producing this work. See http://www.freetype.org for details.
 //
 //----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
 //
 // Adaptation for 32-bit screen coordinates has been sponsored by 
 // Liberty Technology Systems, Inc., visit http://lib-sys.com
@@ -35,12 +26,12 @@
 // PostScript and PDF technology for software developers.
 // 
 //----------------------------------------------------------------------------
-
 #ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED
 #define AGG_RASTERIZER_CELLS_AA_INCLUDED
 
 #include <string.h>
-#include <math.h>
+#include <cstdlib>
+#include <limits>
 #include "agg_math.h"
 #include "agg_array.h"
 
@@ -160,10 +151,10 @@ namespace agg
         m_curr_cell_ptr(0),
         m_sorted_cells(),
         m_sorted_y(),
-        m_min_x(0x7FFFFFFF),
-        m_min_y(0x7FFFFFFF),
-        m_max_x(-0x7FFFFFFF),
-        m_max_y(-0x7FFFFFFF),
+        m_min_x(std::numeric_limits<int>::max()),
+        m_min_y(std::numeric_limits<int>::max()),
+        m_max_x(std::numeric_limits<int>::min()),
+        m_max_y(std::numeric_limits<int>::min()),
         m_sorted(false)
     {
         m_style_cell.initial();
@@ -179,10 +170,10 @@ namespace agg
         m_curr_cell.initial();
         m_style_cell.initial();
         m_sorted = false;
-        m_min_x =  0x7FFFFFFF;
-        m_min_y =  0x7FFFFFFF;
-        m_max_x = -0x7FFFFFFF;
-        m_max_y = -0x7FFFFFFF;
+        m_min_x = std::numeric_limits<int>::max();
+        m_min_y = std::numeric_limits<int>::max();
+        m_max_x = std::numeric_limits<int>::min();
+        m_max_y = std::numeric_limits<int>::min();
     }
 
     //------------------------------------------------------------------------
@@ -227,7 +218,8 @@ namespace agg
         int fx1 = x1 & poly_subpixel_mask;
         int fx2 = x2 & poly_subpixel_mask;
 
-        int delta, p, first, dx;
+        int delta, p, first;
+        long long dx;
         int incr, lift, mod, rem;
 
         //trivial case. Happens often
@@ -252,7 +244,7 @@ namespace agg
         first = poly_subpixel_scale;
         incr  = 1;
 
-        dx = x2 - x1;
+        dx = (long long)x2 - (long long)x1;
 
         if(dx < 0)
         {
@@ -262,13 +254,13 @@ namespace agg
             dx    = -dx;
         }
 
-        delta = p / dx;
-        mod   = p % dx;
+        delta = (int)(p / dx);
+        mod   = (int)(p % dx);
 
         if(mod < 0)
         {
             delta--;
-            mod += dx;
+            mod += static_cast<int>(dx);
         }
 
         m_curr_cell.cover += delta;
@@ -281,16 +273,16 @@ namespace agg
         if(ex1 != ex2)
         {
             p     = poly_subpixel_scale * (y2 - y1 + delta);
-            lift  = p / dx;
-            rem   = p % dx;
+            lift  = (int)(p / dx);
+            rem   = (int)(p % dx);
 
             if (rem < 0)
             {
                 lift--;
-                rem += dx;
+                rem += static_cast<int>(dx);
             }
 
-            mod -= dx;
+            mod -= static_cast<int>(dx);
 
             while (ex1 != ex2)
             {
@@ -298,7 +290,7 @@ namespace agg
                 mod  += rem;
                 if(mod >= 0)
                 {
-                    mod -= dx;
+                    mod -= static_cast<int>(dx);
                     delta++;
                 }
 
@@ -327,17 +319,17 @@ namespace agg
     {
         enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift };
 
-        int dx = x2 - x1;
+        long long dx = (long long)x2 - (long long)x1;
 
         if(dx >= dx_limit || dx <= -dx_limit)
         {
-            int cx = (x1 + x2) >> 1;
-            int cy = (y1 + y2) >> 1;
+            int cx = (int)(((long long)x1 + (long long)x2) >> 1);
+            int cy = (int)(((long long)y1 + (long long)y2) >> 1);
             line(x1, y1, cx, cy);
             line(cx, cy, x2, y2);
         }
 
-        int dy = y2 - y1;
+        long long dy = (long long)y2 - (long long)y1;
         int ex1 = x1 >> poly_subpixel_shift;
         int ex2 = x2 >> poly_subpixel_shift;
         int ey1 = y1 >> poly_subpixel_shift;
@@ -346,7 +338,8 @@ namespace agg
         int fy2 = y2 & poly_subpixel_mask;
 
         int x_from, x_to;
-        int p, rem, mod, lift, delta, first, incr;
+        int rem, mod, lift, delta, first, incr;
+        long long p;
 
         if(ex1 < m_min_x) m_min_x = ex1;
         if(ex1 > m_max_x) m_max_x = ex1;
@@ -423,13 +416,13 @@ namespace agg
             dy    = -dy;
         }
 
-        delta = p / dy;
-        mod   = p % dy;
+        delta = (int)(p / dy);
+        mod   = (int)(p % dy);
 
         if(mod < 0)
         {
             delta--;
-            mod += dy;
+            mod += static_cast<int>(dy);
         }
 
         x_from = x1 + delta;
@@ -441,15 +434,15 @@ namespace agg
         if(ey1 != ey2)
         {
             p     = poly_subpixel_scale * dx;
-            lift  = p / dy;
-            rem   = p % dy;
+            lift  = (int)(p / dy);
+            rem   = (int)(p % dy);
 
             if(rem < 0)
             {
                 lift--;
-                rem += dy;
+                rem += static_cast<int>(dy);
             }
-            mod -= dy;
+            mod -= static_cast<int>(dy);
 
             while(ey1 != ey2)
             {
@@ -457,7 +450,7 @@ namespace agg
                 mod  += rem;
                 if (mod >= 0)
                 {
-                    mod -= dy;
+                    mod -= static_cast<int>(dy);
                     delta++;
                 }
 
@@ -635,8 +628,8 @@ namespace agg
         if(m_sorted) return; //Perform sort only the first time.
 
         add_curr_cell();
-        m_curr_cell.x     = 0x7FFFFFFF;
-        m_curr_cell.y     = 0x7FFFFFFF;
+        m_curr_cell.x     = std::numeric_limits<int>::max();
+        m_curr_cell.y     = std::numeric_limits<int>::max();
         m_curr_cell.cover = 0;
         m_curr_cell.area  = 0;
 
@@ -664,12 +657,13 @@ namespace agg
         // Create the Y-histogram (count the numbers of cells for each Y)
         cell_type** block_ptr = m_cells;
         cell_type*  cell_ptr;
-        unsigned nb = m_num_cells >> cell_block_shift;
+        unsigned nb = m_num_cells;
         unsigned i;
-        while(nb--)
+        while(nb)
         {
             cell_ptr = *block_ptr++;
-            i = cell_block_size;
+            i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb;
+            nb -= i;
             while(i--) 
             {
                 m_sorted_y[cell_ptr->y - m_min_y].start++;
@@ -677,14 +671,6 @@ namespace agg
             }
         }
 
-        cell_ptr = *block_ptr++;
-        i = m_num_cells & cell_block_mask;
-        while(i--) 
-        {
-            m_sorted_y[cell_ptr->y - m_min_y].start++;
-            ++cell_ptr;
-        }
-
         // Convert the Y-histogram into the array of starting indexes
         unsigned start = 0;
         for(i = 0; i < m_sorted_y.size(); i++)
@@ -696,12 +682,13 @@ namespace agg
 
         // Fill the cell pointer array sorted by Y
         block_ptr = m_cells;
-        nb = m_num_cells >> cell_block_shift;
-        while(nb--)
+        nb = m_num_cells;
+        while(nb)
         {
             cell_ptr = *block_ptr++;
-            i = cell_block_size;
-            while(i--) 
+            i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb;
+            nb -= i;
+            while(i--)
             {
                 sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
                 m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
@@ -710,16 +697,6 @@ namespace agg
             }
         }
         
-        cell_ptr = *block_ptr++;
-        i = m_num_cells & cell_block_mask;
-        while(i--) 
-        {
-            sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
-            m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
-            ++curr_y.num;
-            ++cell_ptr;
-        }
-
         // Finally arrange the X-arrays
         for(i = 0; i < m_sorted_y.size(); i++)
         {
diff --git a/src/agg/agg_rasterizer_scanline_aa.h b/src/agg/agg_rasterizer_scanline_aa.h
index 80e138c2e..ffc2ddf94 100644
--- a/src/agg/agg_rasterizer_scanline_aa.h
+++ b/src/agg/agg_rasterizer_scanline_aa.h
@@ -1,25 +1,12 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
 //----------------------------------------------------------------------------
 //
 // The author gratefully acknowleges the support of David Turner, 
@@ -27,6 +14,10 @@
 // libray - in producing this work. See http://www.freetype.org for details.
 //
 //----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
 //
 // Adaptation for 32-bit screen coordinates has been sponsored by 
 // Liberty Technology Systems, Inc., visit http://lib-sys.com
@@ -35,47 +26,17 @@
 // PostScript and PDF technology for software developers.
 // 
 //----------------------------------------------------------------------------
-
 #ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED
 #define AGG_RASTERIZER_SCANLINE_AA_INCLUDED
 
 #include "agg_rasterizer_cells_aa.h"
 #include "agg_rasterizer_sl_clip.h"
+#include "agg_rasterizer_scanline_aa_nogamma.h"
 #include "agg_gamma_functions.h"
 
 
 namespace agg
 {
-
-
-    //-----------------------------------------------------------------cell_aa
-    // A pixel cell. There're no constructors defined and it was done 
-    // intentionally in order to avoid extra overhead when allocating an 
-    // array of cells.
-    struct cell_aa
-    {
-        int x;
-        int y;
-        int cover;
-        int area;
-
-        void initial()
-        {
-            x = 0x7FFFFFFF;
-            y = 0x7FFFFFFF;
-            cover = 0;
-            area  = 0;
-        }
-
-        void style(const cell_aa&) {}
-
-        int not_equal(int ex, int ey, const cell_aa&) const
-        {
-            return (ex - x) | (ey - y);
-        }
-    };
-
-
     //==================================================rasterizer_scanline_aa
     // Polygon rasterizer that is used to render filled polygons with 
     // high-quality Anti-Aliasing. Internally, by default, the class uses 
diff --git a/src/agg/agg_rasterizer_scanline_aa_nogamma.h b/src/agg/agg_rasterizer_scanline_aa_nogamma.h
new file mode 100644
index 000000000..9a809aa5a
--- /dev/null
+++ b/src/agg/agg_rasterizer_scanline_aa_nogamma.h
@@ -0,0 +1,483 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+//
+// The author gratefully acknowleges the support of David Turner, 
+// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType 
+// libray - in producing this work. See http://www.freetype.org for details.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// Adaptation for 32-bit screen coordinates has been sponsored by 
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+// 
+//----------------------------------------------------------------------------
+#ifndef AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
+#define AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
+
+#include <limits>
+#include "agg_rasterizer_cells_aa.h"
+#include "agg_rasterizer_sl_clip.h"
+
+
+namespace agg
+{
+
+
+    //-----------------------------------------------------------------cell_aa
+    // A pixel cell. There're no constructors defined and it was done 
+    // intentionally in order to avoid extra overhead when allocating an 
+    // array of cells.
+    struct cell_aa
+    {
+        int x;
+        int y;
+        int cover;
+        int area;
+
+        void initial()
+        {
+            x = std::numeric_limits<int>::max();
+            y = std::numeric_limits<int>::max();
+            cover = 0;
+            area  = 0;
+        }
+
+        void style(const cell_aa&) {}
+
+        int not_equal(int ex, int ey, const cell_aa&) const
+        {
+            return ((unsigned)ex - (unsigned)x) | ((unsigned)ey - (unsigned)y);
+        }
+    };
+
+
+    //==================================================rasterizer_scanline_aa_nogamma
+    // Polygon rasterizer that is used to render filled polygons with 
+    // high-quality Anti-Aliasing. Internally, by default, the class uses 
+    // integer coordinates in format 24.8, i.e. 24 bits for integer part 
+    // and 8 bits for fractional - see poly_subpixel_shift. This class can be 
+    // used in the following  way:
+    //
+    // 1. filling_rule(filling_rule_e ft) - optional.
+    //
+    // 2. gamma() - optional.
+    //
+    // 3. reset()
+    //
+    // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create 
+    //    more than one contour, but each contour must consist of at least 3
+    //    vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
+    //    is the absolute minimum of vertices that define a triangle.
+    //    The algorithm does not check either the number of vertices nor
+    //    coincidence of their coordinates, but in the worst case it just 
+    //    won't draw anything.
+    //    The orger of the vertices (clockwise or counterclockwise) 
+    //    is important when using the non-zero filling rule (fill_non_zero).
+    //    In this case the vertex order of all the contours must be the same
+    //    if you want your intersecting polygons to be without "holes".
+    //    You actually can use different vertices order. If the contours do not 
+    //    intersect each other the order is not important anyway. If they do, 
+    //    contours with the same vertex order will be rendered without "holes" 
+    //    while the intersecting contours with different orders will have "holes".
+    //
+    // filling_rule() and gamma() can be called anytime before "sweeping".
+    //------------------------------------------------------------------------
+    template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa_nogamma
+    {
+        enum status
+        {
+            status_initial,
+            status_move_to,
+            status_line_to,
+            status_closed
+        };
+
+    public:
+        typedef Clip                      clip_type;
+        typedef typename Clip::conv_type  conv_type;
+        typedef typename Clip::coord_type coord_type;
+
+        enum aa_scale_e
+        {
+            aa_shift  = 8,
+            aa_scale  = 1 << aa_shift,
+            aa_mask   = aa_scale - 1,
+            aa_scale2 = aa_scale * 2,
+            aa_mask2  = aa_scale2 - 1
+        };
+
+        //--------------------------------------------------------------------
+        rasterizer_scanline_aa_nogamma() : 
+            m_outline(),
+            m_clipper(),
+            m_filling_rule(fill_non_zero),
+            m_auto_close(true),
+            m_start_x(0),
+            m_start_y(0),
+            m_status(status_initial)
+        {
+        }
+
+        //--------------------------------------------------------------------
+        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 auto_close(bool flag) { m_auto_close = flag; }
+
+        //--------------------------------------------------------------------
+        unsigned apply_gamma(unsigned cover) const 
+        { 
+            return cover;
+        }
+
+        //--------------------------------------------------------------------
+        void move_to(int x, int y);
+        void line_to(int x, int y);
+        void move_to_d(double x, double y);
+        void line_to_d(double x, double y);
+        void close_polygon();
+        void add_vertex(double x, double y, unsigned cmd);
+
+        void edge(int x1, int y1, int x2, int y2);
+        void edge_d(double x1, double y1, double x2, double y2);
+
+        //-------------------------------------------------------------------
+        template<class VertexSource>
+        void add_path(VertexSource& vs, unsigned path_id=0)
+        {
+            double x;
+            double y;
+
+            unsigned cmd;
+            vs.rewind(path_id);
+            if(m_outline.sorted()) reset();
+            while(!is_stop(cmd = vs.vertex(&x, &y)))
+            {
+                add_vertex(x, y, cmd);
+            }
+        }
+        
+        //--------------------------------------------------------------------
+        int min_x() const { return m_outline.min_x(); }
+        int min_y() const { return m_outline.min_y(); }
+        int max_x() const { return m_outline.max_x(); }
+        int max_y() const { return m_outline.max_y(); }
+
+        //--------------------------------------------------------------------
+        void sort();
+        bool rewind_scanlines();
+        bool navigate_scanline(int y);
+
+        //--------------------------------------------------------------------
+        AGG_INLINE unsigned calculate_alpha(int area) 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;
+        }
+
+        //--------------------------------------------------------------------
+        template<class Scanline> bool sweep_scanline(Scanline& sl)
+        {
+            for(;;)
+            {
+                if(m_scan_y > m_outline.max_y()) return false;
+                sl.reset_spans();
+                unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
+                const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
+                int cover = 0;
+
+                while(num_cells)
+                {
+                    const cell_aa* cur_cell = *cells;
+                    int x    = cur_cell->x;
+                    int area = cur_cell->area;
+                    unsigned alpha;
+
+                    cover += cur_cell->cover;
+
+                    //accumulate all cells with the same X
+                    while(--num_cells)
+                    {
+                        cur_cell = *++cells;
+                        if(cur_cell->x != x) break;
+                        area  += cur_cell->area;
+                        cover += cur_cell->cover;
+                    }
+
+                    if(area)
+                    {
+                        alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
+                        if(alpha)
+                        {
+                            sl.add_cell(x, alpha);
+                        }
+                        x++;
+                    }
+
+                    if(num_cells && cur_cell->x > x)
+                    {
+                        alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
+                        if(alpha)
+                        {
+                            sl.add_span(x, cur_cell->x - x, alpha);
+                        }
+                    }
+                }
+        
+                if(sl.num_spans()) break;
+                ++m_scan_y;
+            }
+
+            sl.finalize(m_scan_y);
+            ++m_scan_y;
+            return true;
+        }
+
+        //--------------------------------------------------------------------
+        bool hit_test(int tx, int ty);
+
+
+    private:
+        //--------------------------------------------------------------------
+        // Disable copying
+        rasterizer_scanline_aa_nogamma(const rasterizer_scanline_aa_nogamma<Clip>&);
+        const rasterizer_scanline_aa_nogamma<Clip>& 
+        operator = (const rasterizer_scanline_aa_nogamma<Clip>&);
+
+    private:
+        rasterizer_cells_aa<cell_aa> m_outline;
+        clip_type      m_clipper;
+        filling_rule_e m_filling_rule;
+        bool           m_auto_close;
+        coord_type     m_start_x;
+        coord_type     m_start_y;
+        unsigned       m_status;
+        int            m_scan_y;
+    };
+
+
+
+
+
+
+
+
+
+
+
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::reset() 
+    { 
+        m_outline.reset(); 
+        m_status = status_initial;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::filling_rule(filling_rule_e filling_rule) 
+    { 
+        m_filling_rule = filling_rule; 
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::clip_box(double x1, double y1, 
+                                                double x2, double y2)
+    {
+        reset();
+        m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1), 
+                           conv_type::upscale(x2), conv_type::upscale(y2));
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::reset_clipping()
+    {
+        reset();
+        m_clipper.reset_clipping();
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::close_polygon()
+    {
+        if(m_status == status_line_to)
+        {
+            m_clipper.line_to(m_outline, m_start_x, m_start_y);
+            m_status = status_closed;
+        }
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::move_to(int x, int y)
+    {
+        if(m_outline.sorted()) reset();
+        if(m_auto_close) close_polygon();
+        m_clipper.move_to(m_start_x = conv_type::downscale(x), 
+                          m_start_y = conv_type::downscale(y));
+        m_status = status_move_to;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::line_to(int x, int y)
+    {
+        m_clipper.line_to(m_outline, 
+                          conv_type::downscale(x), 
+                          conv_type::downscale(y));
+        m_status = status_line_to;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::move_to_d(double x, double y) 
+    { 
+        if(m_outline.sorted()) reset();
+        if(m_auto_close) close_polygon();
+        m_clipper.move_to(m_start_x = conv_type::upscale(x), 
+                          m_start_y = conv_type::upscale(y)); 
+        m_status = status_move_to;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::line_to_d(double x, double y) 
+    { 
+        m_clipper.line_to(m_outline, 
+                          conv_type::upscale(x), 
+                          conv_type::upscale(y)); 
+        m_status = status_line_to;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::add_vertex(double x, double y, unsigned cmd)
+    {
+        if(is_move_to(cmd)) 
+        {
+            move_to_d(x, y);
+        }
+        else 
+        if(is_vertex(cmd))
+        {
+            line_to_d(x, y);
+        }
+        else
+        if(is_close(cmd))
+        {
+            close_polygon();
+        }
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::edge(int x1, int y1, int x2, int y2)
+    {
+        if(m_outline.sorted()) reset();
+        m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
+        m_clipper.line_to(m_outline, 
+                          conv_type::downscale(x2), 
+                          conv_type::downscale(y2));
+        m_status = status_move_to;
+    }
+    
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::edge_d(double x1, double y1, 
+                                              double x2, double y2)
+    {
+        if(m_outline.sorted()) reset();
+        m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1)); 
+        m_clipper.line_to(m_outline, 
+                          conv_type::upscale(x2), 
+                          conv_type::upscale(y2)); 
+        m_status = status_move_to;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_scanline_aa_nogamma<Clip>::sort()
+    {
+        if(m_auto_close) close_polygon();
+        m_outline.sort_cells();
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::rewind_scanlines()
+    {
+        if(m_auto_close) close_polygon();
+        m_outline.sort_cells();
+        if(m_outline.total_cells() == 0) 
+        {
+            return false;
+        }
+        m_scan_y = m_outline.min_y();
+        return true;
+    }
+
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::navigate_scanline(int y)
+    {
+        if(m_auto_close) close_polygon();
+        m_outline.sort_cells();
+        if(m_outline.total_cells() == 0 || 
+           y < m_outline.min_y() || 
+           y > m_outline.max_y()) 
+        {
+            return false;
+        }
+        m_scan_y = y;
+        return true;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    bool rasterizer_scanline_aa_nogamma<Clip>::hit_test(int tx, int ty)
+    {
+        if(!navigate_scanline(ty)) return false;
+        scanline_hit_test sl(tx);
+        sweep_scanline(sl);
+        return sl.hit();
+    }
+
+
+
+}
+
+
+
+#endif
+
diff --git a/src/agg/agg_rasterizer_sl_clip.h b/src/agg/agg_rasterizer_sl_clip.h
index cdfee1af0..3a7f3a103 100644
--- a/src/agg/agg_rasterizer_sl_clip.h
+++ b/src/agg/agg_rasterizer_sl_clip.h
@@ -1,27 +1,17 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
-
 #ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED
 #define AGG_RASTERIZER_SL_CLIP_INCLUDED
 
@@ -327,7 +317,7 @@ namespace agg
         rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
 
         void reset_clipping() {}
-        void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2) {}
+        void clip_box(coord_type, coord_type, coord_type, coord_type) {}
         void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
 
         template<class Rasterizer>
diff --git a/src/agg/agg_renderer_base.h b/src/agg/agg_renderer_base.h
index 180894465..527c62f78 100644
--- a/src/agg/agg_renderer_base.h
+++ b/src/agg/agg_renderer_base.h
@@ -1,25 +1,20 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class renderer_base
+//
 //----------------------------------------------------------------------------
 
 #ifndef AGG_RENDERER_BASE_INCLUDED
@@ -139,6 +134,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)
         {
diff --git a/src/agg/agg_renderer_scanline.h b/src/agg/agg_renderer_scanline.h
index c3bb6f05b..311e9f739 100644
--- a/src/agg/agg_renderer_scanline.h
+++ b/src/agg/agg_renderer_scanline.h
@@ -1,30 +1,23 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
 //----------------------------------------------------------------------------
 
 #ifndef AGG_RENDERER_SCANLINE_INCLUDED
 #define AGG_RENDERER_SCANLINE_INCLUDED
 
+#include <limits>
+#include <cstdlib>
 #include "agg_basics.h"
 #include "agg_renderer_base.h"
 
@@ -74,7 +67,7 @@ namespace agg
             // "rgba8" is needed. Otherwise it will be implicitly 
             // converted in the loop many times.
             //----------------------
-            typename BaseRenderer::color_type ren_color(color);
+            typename BaseRenderer::color_type ren_color = color;
 
             sl.reset(ras.min_x(), ras.max_x());
             while(ras.sweep_scanline(sl))
@@ -754,7 +747,7 @@ namespace agg
                                0, 
                                sl_len * sizeof(cover_type));
 
-                        int sl_y = 0x7FFFFFFF;
+                        int sl_y = std::numeric_limits<int>::max();
                         unsigned i;
                         for(i = 0; i < num_styles; i++)
                         {
diff --git a/src/agg/agg_rendering_buffer.h b/src/agg/agg_rendering_buffer.h
index 3a39caa81..0eff6ff27 100644
--- a/src/agg/agg_rendering_buffer.h
+++ b/src/agg/agg_rendering_buffer.h
@@ -1,25 +1,20 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class rendering_buffer
+//
 //----------------------------------------------------------------------------
 
 #ifndef AGG_RENDERING_BUFFER_INCLUDED
@@ -61,14 +56,14 @@ namespace agg
         //--------------------------------------------------------------------
         void attach(T* buf, unsigned width, unsigned height, int stride)
         {
-			m_buf = m_start = buf;
-			m_width = width;
-			m_height = height;
-			m_stride = stride;
-			if(stride < 0) 
+            m_buf = m_start = buf;
+            m_width = width;
+            m_height = height;
+            m_stride = stride;
+            if(stride < 0) 
             { 
-				m_start = m_buf - int(height - 1) * stride;
-			}
+                m_start = m_buf - int(height - 1) * stride;
+            }
         }
 
         //--------------------------------------------------------------------
@@ -83,13 +78,13 @@ namespace agg
         }
 
         //--------------------------------------------------------------------
-		AGG_INLINE       T* row_ptr(int, int y, unsigned) 
+        AGG_INLINE       T* row_ptr(int, int y, unsigned) 
         { 
             return m_start + y * m_stride; 
         }
-		AGG_INLINE       T* row_ptr(int y)       { return m_start + y * m_stride; }
-		AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; }
-		AGG_INLINE row_data row    (int y) const 
+        AGG_INLINE       T* row_ptr(int y)       { return m_start + y * m_stride; }
+        AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; }
+        AGG_INLINE row_data row    (int y) const 
         { 
             return row_data(0, m_width-1, row_ptr(y)); 
         }
diff --git a/src/agg/agg_scanline_p.h b/src/agg/agg_scanline_p.h
index 0c29638d6..1d1cbe72f 100644
--- a/src/agg/agg_scanline_p.h
+++ b/src/agg/agg_scanline_p.h
@@ -1,25 +1,20 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// Class scanline_p - a general purpose scanline container with packed spans.
+//
 //----------------------------------------------------------------------------
 //
 // Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by 
diff --git a/src/agg/agg_shorten_path.h b/src/agg/agg_shorten_path.h
deleted file mode 100644
index ba72b947b..000000000
--- a/src/agg/agg_shorten_path.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SHORTEN_PATH_INCLUDED
-#define AGG_SHORTEN_PATH_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_vertex_sequence.h"
-
-namespace agg
-{
-
-    //===========================================================shorten_path
-    template<class VertexSequence> 
-    void shorten_path(VertexSequence& vs, double s, unsigned closed = 0)
-    {
-        typedef typename VertexSequence::value_type vertex_type;
-
-        if(s > 0.0 && vs.size() > 1)
-        {
-            double d;
-            int n = int(vs.size() - 2);
-            while(n)
-            {
-                d = vs[n].dist;
-                if(d > s) break;
-                vs.remove_last();
-                s -= d;
-                --n;
-            }
-            if(vs.size() < 2)
-            {
-                vs.remove_all();
-            }
-            else
-            {
-                n = vs.size() - 1;
-                vertex_type& prev = vs[n-1];
-                vertex_type& last = vs[n];
-                d = (prev.dist - s) / prev.dist;
-                double x = prev.x + (last.x - prev.x) * d;
-                double y = prev.y + (last.y - prev.y) * d;
-                last.x = x;
-                last.y = y;
-                if(!prev(last)) vs.remove_last();
-                vs.close(closed != 0);
-            }
-        }
-    }
-
-
-}
-
-#endif
diff --git a/src/agg/agg_trans_affine.h b/src/agg/agg_trans_affine.h
index a662099f2..1a6116388 100644
--- a/src/agg/agg_trans_affine.h
+++ b/src/agg/agg_trans_affine.h
@@ -1,27 +1,21 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (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://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// Affine transformation classes.
+//
 //----------------------------------------------------------------------------
-
 #ifndef AGG_TRANS_AFFINE_INCLUDED
 #define AGG_TRANS_AFFINE_INCLUDED
 
@@ -217,14 +211,14 @@ namespace agg
 
         // Multiply the matrix by 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 the matrix by 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);
         }
@@ -298,7 +292,7 @@ namespace agg
     //------------------------------------------------------------------------
     inline void trans_affine::transform(double* x, double* y) const
     {
-        register double tmp = *x;
+        double tmp = *x;
         *x = tmp * sx  + *y * shx + tx;
         *y = tmp * shy + *y * sy  + ty;
     }
@@ -306,7 +300,7 @@ namespace agg
     //------------------------------------------------------------------------
     inline void trans_affine::transform_2x2(double* x, double* y) const
     {
-        register double tmp = *x;
+        double tmp = *x;
         *x = tmp * sx  + *y * shx;
         *y = tmp * shy + *y * sy;
     }
@@ -314,9 +308,9 @@ namespace agg
     //------------------------------------------------------------------------
     inline void trans_affine::inverse_transform(double* x, double* y) const
     {
-        register double d = determinant_reciprocal();
-        register double a = (*x - tx) * d;
-        register double b = (*y - ty) * d;
+        double d = determinant_reciprocal();
+        double a = (*x - tx) * d;
+        double b = (*y - ty) * d;
         *x = a * sy - b * shx;
         *y = b * sx - a * shy;
     }
diff --git a/src/agg/agg_vcgen_contour.h b/src/agg/agg_vcgen_contour.h
deleted file mode 100644
index 1a3a4bcad..000000000
--- a/src/agg/agg_vcgen_contour.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_VCGEN_CONTOUR_INCLUDED
-#define AGG_VCGEN_CONTOUR_INCLUDED
-
-#include "agg_math_stroke.h"
-
-namespace agg
-{
-
-    //----------------------------------------------------------vcgen_contour
-    //
-    // See Implementation agg_vcgen_contour.cpp
-    //
-    class vcgen_contour
-    {
-        enum status_e
-        {
-            initial,
-            ready,
-            outline,
-            out_vertices,
-            end_poly,
-            stop
-        };
-
-    public:
-        typedef vertex_sequence<vertex_dist, 6> vertex_storage;
-        typedef pod_bvector<point_d, 6>         coord_storage;
-
-        vcgen_contour();
-
-        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); }
-
-        double width() const { return m_width; }
-        double miter_limit() const { return m_stroker.miter_limit(); }
-        double inner_miter_limit() const { return m_stroker.inner_miter_limit(); }
-        double approximation_scale() const { return m_stroker.approximation_scale(); }
-
-        void auto_detect_orientation(bool v) { m_auto_detect = v; }
-        bool auto_detect_orientation() const { return m_auto_detect; }
-
-        // Generator interface
-        void remove_all();
-        void add_vertex(double x, double y, unsigned cmd);
-
-        // Vertex Source Interface
-        void     rewind(unsigned path_id);
-        unsigned vertex(double* x, double* y);
-
-    private:
-        vcgen_contour(const vcgen_contour&);
-        const vcgen_contour& operator = (const vcgen_contour&);
-
-        math_stroke<coord_storage> 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;
-    };
-
-}
-
-#endif
diff --git a/src/agg/agg_vcgen_stroke.h b/src/agg/agg_vcgen_stroke.h
deleted file mode 100644
index 4edba7660..000000000
--- a/src/agg/agg_vcgen_stroke.h
+++ /dev/null
@@ -1,111 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_VCGEN_STROKE_INCLUDED
-#define AGG_VCGEN_STROKE_INCLUDED
-
-#include "agg_math_stroke.h"
-
-
-namespace agg
-{
-
-    //============================================================vcgen_stroke
-    //
-    // See Implementation agg_vcgen_stroke.cpp
-    // Stroke generator
-    //
-    //------------------------------------------------------------------------
-    class vcgen_stroke
-    {
-        enum status_e
-        {
-            initial,
-            ready,
-            cap1,
-            cap2,
-            outline1,
-            close_first,
-            outline2,
-            out_vertices,
-            end_poly1,
-            end_poly2,
-            stop
-        };
-
-    public:
-        typedef vertex_sequence<vertex_dist, 6> vertex_storage;
-        typedef pod_bvector<point_d, 6>         coord_storage;
-
-        vcgen_stroke();
-
-        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(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_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; }
-
-        // Vertex Generator Interface
-        void remove_all();
-        void add_vertex(double x, double y, unsigned cmd);
-
-        // Vertex Source Interface
-        void     rewind(unsigned path_id);
-        unsigned vertex(double* x, double* y);
-
-    private:
-        vcgen_stroke(const vcgen_stroke&);
-        const vcgen_stroke& operator = (const vcgen_stroke&);
-
-        math_stroke<coord_storage> 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;
-    };
-
-
-}
-
-#endif
diff --git a/src/agg/agg_vertex_sequence.h b/src/agg/agg_vertex_sequence.h
deleted file mode 100644
index f3ef35cf1..000000000
--- a/src/agg/agg_vertex_sequence.h
+++ /dev/null
@@ -1,178 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#ifndef AGG_VERTEX_SEQUENCE_INCLUDED
-#define AGG_VERTEX_SEQUENCE_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_array.h"
-#include "agg_math.h"
-
-namespace agg
-{
-
-    //----------------------------------------------------------vertex_sequence
-    // Modified agg::pod_bvector. The data is interpreted as a sequence 
-    // of vertices. It means that the type T must expose:
-    //
-    // 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 
-    // adding and to return true if the vertex fits some criteria or false if
-    // it doesn't. In the last case the new vertex is not added. 
-    // 
-    // The simple example is filtering coinciding vertices with calculation 
-    // of the distance between the current and previous ones:
-    //
-    //    struct vertex_dist
-    //    {
-    //        double   x;
-    //        double   y;
-    //        double   dist;
-    //
-    //        vertex_dist() {}
-    //        vertex_dist(double x_, double y_) :
-    //            x(x_),
-    //            y(y_),
-    //            dist(0.0)
-    //        {
-    //        }
-    //
-    //        bool operator () (const vertex_dist& val)
-    //        {
-    //            return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON;
-    //        }
-    //    };
-    //
-    // Function close() calls this operator and removes the last vertex if 
-    // necessary.
-    //------------------------------------------------------------------------
-    template<class T, unsigned S=6> 
-    class vertex_sequence : public pod_bvector<T, S>
-    {
-    public:
-        typedef pod_bvector<T, S> base_type;
-
-        void add(const T& val);
-        void modify_last(const T& val);
-        void close(bool remove_flag);
-    };
-
-
-
-    //------------------------------------------------------------------------
-    template<class T, unsigned S> 
-    void vertex_sequence<T, S>::add(const T& val)
-    {
-        if(base_type::size() > 1)
-        {
-            if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) 
-            {
-                base_type::remove_last();
-            }
-        }
-        base_type::add(val);
-    }
-
-
-    //------------------------------------------------------------------------
-    template<class T, unsigned S> 
-    void vertex_sequence<T, S>::modify_last(const T& val)
-    {
-        base_type::remove_last();
-        add(val);
-    }
-
-
-
-    //------------------------------------------------------------------------
-    template<class T, unsigned S> 
-    void vertex_sequence<T, S>::close(bool closed)
-    {
-        while(base_type::size() > 1)
-        {
-            if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) break;
-            T t = (*this)[base_type::size() - 1];
-            base_type::remove_last();
-            modify_last(t);
-        }
-
-        if(closed)
-        {
-            while(base_type::size() > 1)
-            {
-                if((*this)[base_type::size() - 1]((*this)[0])) break;
-                base_type::remove_last();
-            }
-        }
-    }
-
-
-    //-------------------------------------------------------------vertex_dist
-    // Vertex (x, y) with the distance to the next one. The last vertex has 
-    // distance between the last and the first points if the polygon is closed
-    // and 0.0 if it's a polyline.
-    struct vertex_dist
-    {
-        double   x;
-        double   y;
-        double   dist;
-
-        vertex_dist() {}
-        vertex_dist(double x_, double y_) :
-            x(x_),
-            y(y_),
-            dist(0.0)
-        {
-        }
-
-        bool operator () (const vertex_dist& val)
-        {
-            bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon;
-            if(!ret) dist = 1.0 / vertex_dist_epsilon;
-            return ret;
-        }
-    };
-
-
-
-    //--------------------------------------------------------vertex_dist_cmd
-    // Save as the above but with additional "command" value
-    struct vertex_dist_cmd : public vertex_dist
-    {
-        unsigned cmd;
-
-        vertex_dist_cmd() {}
-        vertex_dist_cmd(double x_, double y_, unsigned cmd_) :
-            vertex_dist(x_, y_),
-            cmd(cmd_)
-        {
-        }
-    };
-
-
-}
-
-#endif
diff --git a/src/agg/copying b/src/agg/copying
index d511905c1..b6028e519 100644
--- a/src/agg/copying
+++ b/src/agg/copying
@@ -1,339 +1,65 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
+The Anti-Grain Geometry Project
+A high quality rendering engine for C++
+http://antigrain.com
 
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
+Anti-Grain Geometry has dual licensing model. The Modified BSD 
+License was first added in version v2.4 just for convenience.
+It is a simple, permissive non-copyleft free software license, 
+compatible with the GNU GPL. It's well proven and recognizable.
+See http://www.fsf.org/licensing/licenses/index_html#ModifiedBSD
+for details.
 
-			    Preamble
+Note that the Modified BSD license DOES NOT restrict your rights 
+if you choose the Anti-Grain Geometry Public License.
 
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
 
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
 
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
 
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
+Anti-Grain Geometry Public License
+====================================================
 
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
+Anti-Grain Geometry - Version 2.4 
+Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) 
 
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
+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.
 
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
 
-  The precise terms and conditions for copying, distribution and
-modification follow.
 
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
 
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
+Modified BSD License
+====================================================
+Anti-Grain Geometry - Version 2.4 
+Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) 
 
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions 
+are met:
 
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
+  1. Redistributions of source code must retain the above copyright 
+     notice, this list of conditions and the following disclaimer. 
 
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the 
+     distribution. 
 
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
+  3. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior 
+     written permission. 
 
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+POSSIBILITY OF SUCH DAMAGE.
 
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/src/agg_svg/CMakeLists.txt b/src/agg_svg/CMakeLists.txt
deleted file mode 100644
index 5790ce9e9..000000000
--- a/src/agg_svg/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-project(agg_svg)
-cmake_minimum_required(VERSION 2.6)
-
-add_library(agg_svg STATIC 
-	agg_svg_exception.h
-	agg_svg_parser.cpp
-	agg_svg_parser.h
-	agg_svg_path_renderer.cpp
-	agg_svg_path_renderer.h
-	agg_svg_path_tokenizer.cpp
-	agg_svg_path_tokenizer.h
-
-#	agg_bezier_arc.cpp
-	agg_curves.cpp
-	agg_trans_affine.cpp
-	agg_vcgen_contour.cpp
-	agg_vcgen_stroke.cpp
-	)
-
-target_include_directories(agg_svg PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
-
-target_link_libraries(agg_svg ${EXPAT_LIBRARIES})
diff --git a/src/agg_svg/agg_bezier_arc.cpp b/src/agg_svg/agg_bezier_arc.cpp
deleted file mode 100644
index 8d5425a35..000000000
--- a/src/agg_svg/agg_bezier_arc.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#include <math.h>
-#include "agg_bezier_arc.h"
-
-
-namespace agg
-{
-
-    // This epsilon is used to prevent us from adding degenerate curves 
-    // (converging to a single point).
-    // The value isn't very critical. Function arc_to_bezier() has a limit 
-    // of the sweep_angle. If fabs(sweep_angle) exceeds pi/2 the curve 
-    // becomes inaccurate. But slight exceeding is quite appropriate.
-    //-------------------------------------------------bezier_arc_angle_epsilon
-    const double bezier_arc_angle_epsilon = 0.01;
-
-    //------------------------------------------------------------arc_to_bezier
-    void arc_to_bezier(double cx, double cy, double rx, double ry, 
-                       double start_angle, double sweep_angle,
-                       double* curve)
-    {
-        double x0 = cos(sweep_angle / 2.0);
-        double y0 = sin(sweep_angle / 2.0);
-        double tx = (1.0 - x0) * 4.0 / 3.0;
-        double ty = y0 - tx * x0 / y0;
-        double px[4];
-        double py[4];
-        px[0] =  x0;
-        py[0] = -y0;
-        px[1] =  x0 + tx;
-        py[1] = -ty;
-        px[2] =  x0 + tx;
-        py[2] =  ty;
-        px[3] =  x0;
-        py[3] =  y0;
-
-        double sn = sin(start_angle + sweep_angle / 2.0);
-        double cs = cos(start_angle + sweep_angle / 2.0);
-
-        unsigned i;
-        for(i = 0; i < 4; i++)
-        {
-            curve[i * 2]     = cx + rx * (px[i] * cs - py[i] * sn);
-            curve[i * 2 + 1] = cy + ry * (px[i] * sn + py[i] * cs);
-        }
-    }
-
-
-
-    //------------------------------------------------------------------------
-    void bezier_arc::init(double x,  double y, 
-                          double rx, double ry, 
-                          double start_angle, 
-                          double sweep_angle)
-    {
-        start_angle = fmod(start_angle, 2.0 * pi);
-        if(sweep_angle >=  2.0 * pi) sweep_angle =  2.0 * pi;
-        if(sweep_angle <= -2.0 * pi) sweep_angle = -2.0 * pi;
-
-        if(fabs(sweep_angle) < 1e-10)
-        {
-            m_num_vertices = 4;
-            m_cmd = path_cmd_line_to;
-            m_vertices[0] = x + rx * cos(start_angle);
-            m_vertices[1] = y + ry * sin(start_angle);
-            m_vertices[2] = x + rx * cos(start_angle + sweep_angle);
-            m_vertices[3] = y + ry * sin(start_angle + sweep_angle);
-            return;
-        }
-
-        double total_sweep = 0.0;
-        double local_sweep = 0.0;
-        double prev_sweep;
-        m_num_vertices = 2;
-        m_cmd = path_cmd_curve4;
-        bool done = false;
-        do
-        {
-            if(sweep_angle < 0.0)
-            {
-                prev_sweep  = total_sweep;
-                local_sweep = -pi * 0.5;
-                total_sweep -= pi * 0.5;
-                if(total_sweep <= sweep_angle + bezier_arc_angle_epsilon)
-                {
-                    local_sweep = sweep_angle - prev_sweep;
-                    done = true;
-                }
-            }
-            else
-            {
-                prev_sweep  = total_sweep;
-                local_sweep =  pi * 0.5;
-                total_sweep += pi * 0.5;
-                if(total_sweep >= sweep_angle - bezier_arc_angle_epsilon)
-                {
-                    local_sweep = sweep_angle - prev_sweep;
-                    done = true;
-                }
-            }
-
-            arc_to_bezier(x, y, rx, ry, 
-                          start_angle, 
-                          local_sweep, 
-                          m_vertices + m_num_vertices - 2);
-
-            m_num_vertices += 6;
-            start_angle += local_sweep;
-        }
-        while(!done && m_num_vertices < 26);
-    }
-
-
-
-
-    //--------------------------------------------------------------------
-    void bezier_arc_svg::init(double x0, double y0, 
-                              double rx, double ry, 
-                              double angle,
-                              bool large_arc_flag,
-                              bool sweep_flag,
-                              double x2, double y2)
-    {
-        m_radii_ok = true;
-
-        if(rx < 0.0) rx = -rx;
-        if(ry < 0.0) ry = -rx;
-
-        // Calculate the middle point between 
-        // the current and the final points
-        //------------------------
-        double dx2 = (x0 - x2) / 2.0;
-        double dy2 = (y0 - y2) / 2.0;
-
-        double cos_a = cos(angle);
-        double sin_a = sin(angle);
-
-        // Calculate (x1, y1)
-        //------------------------
-        double x1 =  cos_a * dx2 + sin_a * dy2;
-        double y1 = -sin_a * dx2 + cos_a * dy2;
-
-        // Ensure radii are large enough
-        //------------------------
-        double prx = rx * rx;
-        double pry = ry * ry;
-        double px1 = x1 * x1;
-        double py1 = y1 * y1;
-
-        // Check that radii are large enough
-        //------------------------
-        double radii_check = px1/prx + py1/pry;
-        if(radii_check > 1.0) 
-        {
-            rx = sqrt(radii_check) * rx;
-            ry = sqrt(radii_check) * ry;
-            prx = rx * rx;
-            pry = ry * ry;
-            if(radii_check > 10.0) m_radii_ok = false;
-        }
-
-        // Calculate (cx1, cy1)
-        //------------------------
-        double sign = (large_arc_flag == sweep_flag) ? -1.0 : 1.0;
-        double sq   = (prx*pry - prx*py1 - pry*px1) / (prx*py1 + pry*px1);
-        double coef = sign * sqrt((sq < 0) ? 0 : sq);
-        double cx1  = coef *  ((rx * y1) / ry);
-        double cy1  = coef * -((ry * x1) / rx);
-
-        //
-        // Calculate (cx, cy) from (cx1, cy1)
-        //------------------------
-        double sx2 = (x0 + x2) / 2.0;
-        double sy2 = (y0 + y2) / 2.0;
-        double cx = sx2 + (cos_a * cx1 - sin_a * cy1);
-        double cy = sy2 + (sin_a * cx1 + cos_a * cy1);
-
-        // Calculate the start_angle (angle1) and the sweep_angle (dangle)
-        //------------------------
-        double ux =  (x1 - cx1) / rx;
-        double uy =  (y1 - cy1) / ry;
-        double vx = (-x1 - cx1) / rx;
-        double vy = (-y1 - cy1) / ry;
-        double p, n;
-
-        // Calculate the angle start
-        //------------------------
-        n = sqrt(ux*ux + uy*uy);
-        p = ux; // (1 * ux) + (0 * uy)
-        sign = (uy < 0) ? -1.0 : 1.0;
-        double v = p / n;
-        if(v < -1.0) v = -1.0;
-        if(v >  1.0) v =  1.0;
-        double start_angle = sign * acos(v);
-
-        // Calculate the sweep angle
-        //------------------------
-        n = sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy));
-        p = ux * vx + uy * vy;
-        sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0;
-        v = p / n;
-        if(v < -1.0) v = -1.0;
-        if(v >  1.0) v =  1.0;
-        double sweep_angle = sign * acos(v);
-        if(!sweep_flag && sweep_angle > 0) 
-        {
-            sweep_angle -= pi * 2.0;
-        } 
-        else 
-        if (sweep_flag && sweep_angle < 0) 
-        {
-            sweep_angle += pi * 2.0;
-        }
-
-        // We can now build and transform the resulting arc
-        //------------------------
-        m_arc.init(0.0, 0.0, rx, ry, start_angle, sweep_angle);
-        trans_affine mtx = trans_affine_rotation(angle);
-        mtx *= trans_affine_translation(cx, cy);
-        
-        for(unsigned i = 2; i < m_arc.num_vertices()-2; i += 2)
-        {
-            mtx.transform(m_arc.vertices() + i, m_arc.vertices() + i + 1);
-        }
-
-        // We must make sure that the starting and ending points
-        // exactly coincide with the initial (x0,y0) and (x2,y2)
-        m_arc.vertices()[0] = x0;
-        m_arc.vertices()[1] = y0;
-        if(m_arc.num_vertices() > 2)
-        {
-            m_arc.vertices()[m_arc.num_vertices() - 2] = x2;
-            m_arc.vertices()[m_arc.num_vertices() - 1] = y2;
-        }
-    }
-
-
-}
diff --git a/src/agg_svg/agg_curves.cpp b/src/agg_svg/agg_curves.cpp
deleted file mode 100644
index 2f2d288e3..000000000
--- a/src/agg_svg/agg_curves.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#include <math.h>
-#include <agg/agg_curves.h>
-#include <agg/agg_math.h>
-
-namespace agg
-{
-
-    //------------------------------------------------------------------------
-    const double curve_distance_epsilon                  = 1e-30;
-    const double curve_collinearity_epsilon              = 1e-30;
-    const double curve_angle_tolerance_epsilon           = 0.01;
-    enum curve_recursion_limit_e { curve_recursion_limit = 32 };
-
-
-
-    //------------------------------------------------------------------------
-    void curve3_inc::approximation_scale(double s) 
-    { 
-        m_scale = s;
-    }
-
-    //------------------------------------------------------------------------
-    double curve3_inc::approximation_scale() const 
-    { 
-        return m_scale;
-    }
-
-    //------------------------------------------------------------------------
-    void curve3_inc::init(double x1, double y1, 
-                          double x2, double y2, 
-                          double x3, double y3)
-    {
-        m_start_x = x1;
-        m_start_y = y1;
-        m_end_x   = x3;
-        m_end_y   = y3;
-
-        double dx1 = x2 - x1;
-        double dy1 = y2 - y1;
-        double dx2 = x3 - x2;
-        double dy2 = y3 - y2;
-
-        double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2); 
-
-        m_num_steps = uround(len * 0.25 * m_scale);
-
-        if(m_num_steps < 4)
-        {
-            m_num_steps = 4;   
-        }
-
-        double subdivide_step  = 1.0 / m_num_steps;
-        double subdivide_step2 = subdivide_step * subdivide_step;
-
-        double tmpx = (x1 - x2 * 2.0 + x3) * subdivide_step2;
-        double tmpy = (y1 - y2 * 2.0 + y3) * subdivide_step2;
-
-        m_saved_fx = m_fx = x1;
-        m_saved_fy = m_fy = y1;
-        
-        m_saved_dfx = m_dfx = tmpx + (x2 - x1) * (2.0 * subdivide_step);
-        m_saved_dfy = m_dfy = tmpy + (y2 - y1) * (2.0 * subdivide_step);
-
-        m_ddfx = tmpx * 2.0;
-        m_ddfy = tmpy * 2.0;
-
-        m_step = m_num_steps;
-    }
-
-    //------------------------------------------------------------------------
-    void curve3_inc::rewind(unsigned)
-    {
-        if(m_num_steps == 0)
-        {
-            m_step = -1;
-            return;
-        }
-        m_step = m_num_steps;
-        m_fx   = m_saved_fx;
-        m_fy   = m_saved_fy;
-        m_dfx  = m_saved_dfx;
-        m_dfy  = m_saved_dfy;
-    }
-
-    //------------------------------------------------------------------------
-    unsigned curve3_inc::vertex(double* x, double* y)
-    {
-        if(m_step < 0) return path_cmd_stop;
-        if(m_step == m_num_steps)
-        {
-            *x = m_start_x;
-            *y = m_start_y;
-            --m_step;
-            return path_cmd_move_to;
-        }
-        if(m_step == 0)
-        {
-            *x = m_end_x;
-            *y = m_end_y;
-            --m_step;
-            return path_cmd_line_to;
-        }
-        m_fx  += m_dfx; 
-        m_fy  += m_dfy;
-        m_dfx += m_ddfx; 
-        m_dfy += m_ddfy; 
-        *x = m_fx;
-        *y = m_fy;
-        --m_step;
-        return path_cmd_line_to;
-    }
-
-    //------------------------------------------------------------------------
-    void curve3_div::init(double x1, double y1, 
-                          double x2, double y2, 
-                          double x3, double y3)
-    {
-        m_points.remove_all();
-        m_distance_tolerance_square = 0.5 / m_approximation_scale;
-        m_distance_tolerance_square *= m_distance_tolerance_square;
-        bezier(x1, y1, x2, y2, x3, y3);
-        m_count = 0;
-    }
-
-    //------------------------------------------------------------------------
-    void curve3_div::recursive_bezier(double x1, double y1, 
-                                      double x2, double y2, 
-                                      double x3, double y3,
-                                      unsigned level)
-    {
-        if(level > curve_recursion_limit) 
-        {
-            return;
-        }
-
-        // Calculate all the mid-points of the line segments
-        //----------------------
-        double x12   = (x1 + x2) / 2;                
-        double y12   = (y1 + y2) / 2;
-        double x23   = (x2 + x3) / 2;
-        double y23   = (y2 + y3) / 2;
-        double x123  = (x12 + x23) / 2;
-        double y123  = (y12 + y23) / 2;
-
-        double dx = x3-x1;
-        double dy = y3-y1;
-        double d = fabs(((x2 - x3) * dy - (y2 - y3) * dx));
-        double da;
-
-        if(d > curve_collinearity_epsilon)
-        { 
-            // Regular case
-            //-----------------
-            if(d * d <= m_distance_tolerance_square * (dx*dx + dy*dy))
-            {
-                // If the curvature doesn't exceed the distance_tolerance value
-                // we tend to finish subdivisions.
-                //----------------------
-                if(m_angle_tolerance < curve_angle_tolerance_epsilon)
-                {
-                    m_points.add(point_d(x123, y123));
-                    return;
-                }
-
-                // Angle & Cusp Condition
-                //----------------------
-                da = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1));
-                if(da >= pi) da = 2*pi - da;
-
-                if(da < m_angle_tolerance)
-                {
-                    // Finally we can stop the recursion
-                    //----------------------
-                    m_points.add(point_d(x123, y123));
-                    return;                 
-                }
-            }
-        }
-        else
-        {
-            // Collinear case
-            //------------------
-            da = dx*dx + dy*dy;
-            if(da == 0)
-            {
-                d = calc_sq_distance(x1, y1, x2, y2);
-            }
-            else
-            {
-                d = ((x2 - x1)*dx + (y2 - y1)*dy) / da;
-                if(d > 0 && d < 1)
-                {
-                    // Simple collinear case, 1---2---3
-                    // We can leave just two endpoints
-                    return;
-                }
-                     if(d <= 0) d = calc_sq_distance(x2, y2, x1, y1);
-                else if(d >= 1) d = calc_sq_distance(x2, y2, x3, y3);
-                else            d = calc_sq_distance(x2, y2, x1 + d*dx, y1 + d*dy);
-            }
-            if(d < m_distance_tolerance_square)
-            {
-                m_points.add(point_d(x2, y2));
-                return;
-            }
-        }
-
-        // Continue subdivision
-        //----------------------
-        recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1); 
-        recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1); 
-    }
-
-    //------------------------------------------------------------------------
-    void curve3_div::bezier(double x1, double y1, 
-                            double x2, double y2, 
-                            double x3, double y3)
-    {
-        m_points.add(point_d(x1, y1));
-        recursive_bezier(x1, y1, x2, y2, x3, y3, 0);
-        m_points.add(point_d(x3, y3));
-    }
-
-
-
-
-
-    //------------------------------------------------------------------------
-    void curve4_inc::approximation_scale(double s) 
-    { 
-        m_scale = s;
-    }
-
-    //------------------------------------------------------------------------
-    double curve4_inc::approximation_scale() const 
-    { 
-        return m_scale;
-    }
-
-    //------------------------------------------------------------------------
-    static double MSC60_fix_ICE(double v) { return v; }
-
-    //------------------------------------------------------------------------
-    void curve4_inc::init(double x1, double y1, 
-                          double x2, double y2, 
-                          double x3, double y3,
-                          double x4, double y4)
-    {
-        m_start_x = x1;
-        m_start_y = y1;
-        m_end_x   = x4;
-        m_end_y   = y4;
-
-        double dx1 = x2 - x1;
-        double dy1 = y2 - y1;
-        double dx2 = x3 - x2;
-        double dy2 = y3 - y2;
-        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;
-
-#if defined(_MSC_VER) && _MSC_VER <= 1200
-        m_num_steps = uround(MSC60_fix_ICE(len));
-#else
-        m_num_steps = uround(len);
-#endif
-
-        if(m_num_steps < 4)
-        {
-            m_num_steps = 4;   
-        }
-
-        double subdivide_step  = 1.0 / m_num_steps;
-        double subdivide_step2 = subdivide_step * subdivide_step;
-        double subdivide_step3 = subdivide_step * subdivide_step * subdivide_step;
-
-        double pre1 = 3.0 * subdivide_step;
-        double pre2 = 3.0 * subdivide_step2;
-        double pre4 = 6.0 * subdivide_step2;
-        double pre5 = 6.0 * subdivide_step3;
-	
-        double tmp1x = x1 - x2 * 2.0 + x3;
-        double tmp1y = y1 - y2 * 2.0 + y3;
-
-        double tmp2x = (x2 - x3) * 3.0 - x1 + x4;
-        double tmp2y = (y2 - y3) * 3.0 - y1 + y4;
-
-        m_saved_fx = m_fx = x1;
-        m_saved_fy = m_fy = y1;
-
-        m_saved_dfx = m_dfx = (x2 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdivide_step3;
-        m_saved_dfy = m_dfy = (y2 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdivide_step3;
-
-        m_saved_ddfx = m_ddfx = tmp1x * pre4 + tmp2x * pre5;
-        m_saved_ddfy = m_ddfy = tmp1y * pre4 + tmp2y * pre5;
-
-        m_dddfx = tmp2x * pre5;
-        m_dddfy = tmp2y * pre5;
-
-        m_step = m_num_steps;
-    }
-
-    //------------------------------------------------------------------------
-    void curve4_inc::rewind(unsigned)
-    {
-        if(m_num_steps == 0)
-        {
-            m_step = -1;
-            return;
-        }
-        m_step = m_num_steps;
-        m_fx   = m_saved_fx;
-        m_fy   = m_saved_fy;
-        m_dfx  = m_saved_dfx;
-        m_dfy  = m_saved_dfy;
-        m_ddfx = m_saved_ddfx;
-        m_ddfy = m_saved_ddfy;
-    }
-
-    //------------------------------------------------------------------------
-    unsigned curve4_inc::vertex(double* x, double* y)
-    {
-        if(m_step < 0) return path_cmd_stop;
-        if(m_step == m_num_steps)
-        {
-            *x = m_start_x;
-            *y = m_start_y;
-            --m_step;
-            return path_cmd_move_to;
-        }
-
-        if(m_step == 0)
-        {
-            *x = m_end_x;
-            *y = m_end_y;
-            --m_step;
-            return path_cmd_line_to;
-        }
-
-        m_fx   += m_dfx;
-        m_fy   += m_dfy;
-        m_dfx  += m_ddfx; 
-        m_dfy  += m_ddfy; 
-        m_ddfx += m_dddfx; 
-        m_ddfy += m_dddfy; 
-
-        *x = m_fx;
-        *y = m_fy;
-        --m_step;
-        return path_cmd_line_to;
-    }
-
-
-
-
-    //------------------------------------------------------------------------
-    void curve4_div::init(double x1, double y1, 
-                          double x2, double y2, 
-                          double x3, double y3,
-                          double x4, double y4)
-    {
-        m_points.remove_all();
-        m_distance_tolerance_square = 0.5 / m_approximation_scale;
-        m_distance_tolerance_square *= m_distance_tolerance_square;
-        bezier(x1, y1, x2, y2, x3, y3, x4, y4);
-        m_count = 0;
-    }
-
-    //------------------------------------------------------------------------
-    void curve4_div::recursive_bezier(double x1, double y1, 
-                                      double x2, double y2, 
-                                      double x3, double y3, 
-                                      double x4, double y4,
-                                      unsigned level)
-    {
-        if(level > curve_recursion_limit) 
-        {
-            return;
-        }
-
-        // Calculate all the mid-points of the line segments
-        //----------------------
-        double x12   = (x1 + x2) / 2;
-        double y12   = (y1 + y2) / 2;
-        double x23   = (x2 + x3) / 2;
-        double y23   = (y2 + y3) / 2;
-        double x34   = (x3 + x4) / 2;
-        double y34   = (y3 + y4) / 2;
-        double x123  = (x12 + x23) / 2;
-        double y123  = (y12 + y23) / 2;
-        double x234  = (x23 + x34) / 2;
-        double y234  = (y23 + y34) / 2;
-        double x1234 = (x123 + x234) / 2;
-        double y1234 = (y123 + y234) / 2;
-
-
-        // Try to approximate the full cubic curve by a single straight line
-        //------------------
-        double dx = x4-x1;
-        double dy = y4-y1;
-
-        double d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx));
-        double d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx));
-        double da1, da2, k;
-
-        switch((int(d2 > curve_collinearity_epsilon) << 1) +
-                int(d3 > curve_collinearity_epsilon))
-        {
-        case 0:
-            // All collinear OR p1==p4
-            //----------------------
-            k = dx*dx + dy*dy;
-            if(k == 0)
-            {
-                d2 = calc_sq_distance(x1, y1, x2, y2);
-                d3 = calc_sq_distance(x4, y4, x3, y3);
-            }
-            else
-            {
-                k   = 1 / k;
-                da1 = x2 - x1;
-                da2 = y2 - y1;
-                d2  = k * (da1*dx + da2*dy);
-                da1 = x3 - x1;
-                da2 = y3 - y1;
-                d3  = k * (da1*dx + da2*dy);
-                if(d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1)
-                {
-                    // Simple collinear case, 1---2---3---4
-                    // We can leave just two endpoints
-                    return;
-                }
-                     if(d2 <= 0) d2 = calc_sq_distance(x2, y2, x1, y1);
-                else if(d2 >= 1) d2 = calc_sq_distance(x2, y2, x4, y4);
-                else             d2 = calc_sq_distance(x2, y2, x1 + d2*dx, y1 + d2*dy);
-
-                     if(d3 <= 0) d3 = calc_sq_distance(x3, y3, x1, y1);
-                else if(d3 >= 1) d3 = calc_sq_distance(x3, y3, x4, y4);
-                else             d3 = calc_sq_distance(x3, y3, x1 + d3*dx, y1 + d3*dy);
-            }
-            if(d2 > d3)
-            {
-                if(d2 < m_distance_tolerance_square)
-                {
-                    m_points.add(point_d(x2, y2));
-                    return;
-                }
-            }
-            else
-            {
-                if(d3 < m_distance_tolerance_square)
-                {
-                    m_points.add(point_d(x3, y3));
-                    return;
-                }
-            }
-            break;
-
-        case 1:
-            // p1,p2,p4 are collinear, p3 is significant
-            //----------------------
-            if(d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy))
-            {
-                if(m_angle_tolerance < curve_angle_tolerance_epsilon)
-                {
-                    m_points.add(point_d(x23, y23));
-                    return;
-                }
-
-                // Angle Condition
-                //----------------------
-                da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2));
-                if(da1 >= pi) da1 = 2*pi - da1;
-
-                if(da1 < m_angle_tolerance)
-                {
-                    m_points.add(point_d(x2, y2));
-                    m_points.add(point_d(x3, y3));
-                    return;
-                }
-
-                if(m_cusp_limit != 0.0)
-                {
-                    if(da1 > m_cusp_limit)
-                    {
-                        m_points.add(point_d(x3, y3));
-                        return;
-                    }
-                }
-            }
-            break;
-
-        case 2:
-            // p1,p3,p4 are collinear, p2 is significant
-            //----------------------
-            if(d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy))
-            {
-                if(m_angle_tolerance < curve_angle_tolerance_epsilon)
-                {
-                    m_points.add(point_d(x23, y23));
-                    return;
-                }
-
-                // Angle Condition
-                //----------------------
-                da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1));
-                if(da1 >= pi) da1 = 2*pi - da1;
-
-                if(da1 < m_angle_tolerance)
-                {
-                    m_points.add(point_d(x2, y2));
-                    m_points.add(point_d(x3, y3));
-                    return;
-                }
-
-                if(m_cusp_limit != 0.0)
-                {
-                    if(da1 > m_cusp_limit)
-                    {
-                        m_points.add(point_d(x2, y2));
-                        return;
-                    }
-                }
-            }
-            break;
-
-        case 3: 
-            // Regular case
-            //-----------------
-            if((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy))
-            {
-                // If the curvature doesn't exceed the distance_tolerance value
-                // we tend to finish subdivisions.
-                //----------------------
-                if(m_angle_tolerance < curve_angle_tolerance_epsilon)
-                {
-                    m_points.add(point_d(x23, y23));
-                    return;
-                }
-
-                // Angle & Cusp Condition
-                //----------------------
-                k   = atan2(y3 - y2, x3 - x2);
-                da1 = fabs(k - atan2(y2 - y1, x2 - x1));
-                da2 = fabs(atan2(y4 - y3, x4 - x3) - k);
-                if(da1 >= pi) da1 = 2*pi - da1;
-                if(da2 >= pi) da2 = 2*pi - da2;
-
-                if(da1 + da2 < m_angle_tolerance)
-                {
-                    // Finally we can stop the recursion
-                    //----------------------
-                    m_points.add(point_d(x23, y23));
-                    return;
-                }
-
-                if(m_cusp_limit != 0.0)
-                {
-                    if(da1 > m_cusp_limit)
-                    {
-                        m_points.add(point_d(x2, y2));
-                        return;
-                    }
-
-                    if(da2 > m_cusp_limit)
-                    {
-                        m_points.add(point_d(x3, y3));
-                        return;
-                    }
-                }
-            }
-            break;
-        }
-
-        // Continue subdivision
-        //----------------------
-        recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); 
-        recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); 
-    }
-
-    //------------------------------------------------------------------------
-    void curve4_div::bezier(double x1, double y1, 
-                            double x2, double y2, 
-                            double x3, double y3, 
-                            double x4, double y4)
-    {
-        m_points.add(point_d(x1, y1));
-        recursive_bezier(x1, y1, x2, y2, x3, y3, x4, y4, 0);
-        m_points.add(point_d(x4, y4));
-    }
-
-}
-
diff --git a/src/agg_svg/agg_svg_exception.h b/src/agg_svg/agg_svg_exception.h
deleted file mode 100644
index 2a49b9938..000000000
--- a/src/agg_svg/agg_svg_exception.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software 
-// is granted provided this copyright notice appears in all copies. 
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// SVG exception
-//
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SVG_EXCEPTION_INCLUDED
-#define AGG_SVG_EXCEPTION_INCLUDED
-
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-
-namespace agg 
-{ 
-namespace svg
-{
-    class exception
-    {
-    public:
-        ~exception()
-        {
-            delete [] m_msg;
-        }
-
-        exception() : m_msg(0) {}
-          
-        exception(const char* fmt, ...) :
-            m_msg(0)
-        {
-            if(fmt) 
-            {
-                m_msg = new char [4096];
-                va_list arg;
-                va_start(arg, fmt);
-                vsprintf(m_msg, fmt, arg);
-                va_end(arg);
-            }
-        }
-
-        exception(const exception& exc) :
-            m_msg(exc.m_msg ? new char[strlen(exc.m_msg) + 1] : 0)
-        {
-            if(m_msg) strcpy(m_msg, exc.m_msg);
-        }
-        
-        const char* msg() const { return m_msg; }
-
-    private:
-        char* m_msg;
-    };
-
-}
-}
-
-#endif
diff --git a/src/agg_svg/agg_svg_parser.cpp b/src/agg_svg/agg_svg_parser.cpp
deleted file mode 100644
index 4eeac31db..000000000
--- a/src/agg_svg/agg_svg_parser.cpp
+++ /dev/null
@@ -1,886 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software 
-// is granted provided this copyright notice appears in all copies. 
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// SVG parser.
-//
-//----------------------------------------------------------------------------
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include "agg_svg_parser.h"
-#include "expat.h"
-
-namespace agg
-{
-namespace svg
-{
-    struct named_color
-    {
-        char  name[22];
-        int8u r, g, b, a;
-    };
-
-    named_color colors[] = 
-    {
-        { "aliceblue",240,248,255, 255 },
-        { "antiquewhite",250,235,215, 255 },
-        { "aqua",0,255,255, 255 },
-        { "aquamarine",127,255,212, 255 },
-        { "azure",240,255,255, 255 },
-        { "beige",245,245,220, 255 },
-        { "bisque",255,228,196, 255 },
-        { "black",0,0,0, 255 },
-        { "blanchedalmond",255,235,205, 255 },
-        { "blue",0,0,255, 255 },
-        { "blueviolet",138,43,226, 255 },
-        { "brown",165,42,42, 255 },
-        { "burlywood",222,184,135, 255 },
-        { "cadetblue",95,158,160, 255 },
-        { "chartreuse",127,255,0, 255 },
-        { "chocolate",210,105,30, 255 },
-        { "coral",255,127,80, 255 },
-        { "cornflowerblue",100,149,237, 255 },
-        { "cornsilk",255,248,220, 255 },
-        { "crimson",220,20,60, 255 },
-        { "cyan",0,255,255, 255 },
-        { "darkblue",0,0,139, 255 },
-        { "darkcyan",0,139,139, 255 },
-        { "darkgoldenrod",184,134,11, 255 },
-        { "darkgray",169,169,169, 255 },
-        { "darkgreen",0,100,0, 255 },
-        { "darkgrey",169,169,169, 255 },
-        { "darkkhaki",189,183,107, 255 },
-        { "darkmagenta",139,0,139, 255 },
-        { "darkolivegreen",85,107,47, 255 },
-        { "darkorange",255,140,0, 255 },
-        { "darkorchid",153,50,204, 255 },
-        { "darkred",139,0,0, 255 },
-        { "darksalmon",233,150,122, 255 },
-        { "darkseagreen",143,188,143, 255 },
-        { "darkslateblue",72,61,139, 255 },
-        { "darkslategray",47,79,79, 255 },
-        { "darkslategrey",47,79,79, 255 },
-        { "darkturquoise",0,206,209, 255 },
-        { "darkviolet",148,0,211, 255 },
-        { "deeppink",255,20,147, 255 },
-        { "deepskyblue",0,191,255, 255 },
-        { "dimgray",105,105,105, 255 },
-        { "dimgrey",105,105,105, 255 },
-        { "dodgerblue",30,144,255, 255 },
-        { "firebrick",178,34,34, 255 },
-        { "floralwhite",255,250,240, 255 },
-        { "forestgreen",34,139,34, 255 },
-        { "fuchsia",255,0,255, 255 },
-        { "gainsboro",220,220,220, 255 },
-        { "ghostwhite",248,248,255, 255 },
-        { "gold",255,215,0, 255 },
-        { "goldenrod",218,165,32, 255 },
-        { "gray",128,128,128, 255 },
-        { "green",0,128,0, 255 },
-        { "greenyellow",173,255,47, 255 },
-        { "grey",128,128,128, 255 },
-        { "honeydew",240,255,240, 255 },
-        { "hotpink",255,105,180, 255 },
-        { "indianred",205,92,92, 255 },
-        { "indigo",75,0,130, 255 },
-        { "ivory",255,255,240, 255 },
-        { "khaki",240,230,140, 255 },
-        { "lavender",230,230,250, 255 },
-        { "lavenderblush",255,240,245, 255 },
-        { "lawngreen",124,252,0, 255 },
-        { "lemonchiffon",255,250,205, 255 },
-        { "lightblue",173,216,230, 255 },
-        { "lightcoral",240,128,128, 255 },
-        { "lightcyan",224,255,255, 255 },
-        { "lightgoldenrodyellow",250,250,210, 255 },
-        { "lightgray",211,211,211, 255 },
-        { "lightgreen",144,238,144, 255 },
-        { "lightgrey",211,211,211, 255 },
-        { "lightpink",255,182,193, 255 },
-        { "lightsalmon",255,160,122, 255 },
-        { "lightseagreen",32,178,170, 255 },
-        { "lightskyblue",135,206,250, 255 },
-        { "lightslategray",119,136,153, 255 },
-        { "lightslategrey",119,136,153, 255 },
-        { "lightsteelblue",176,196,222, 255 },
-        { "lightyellow",255,255,224, 255 },
-        { "lime",0,255,0, 255 },
-        { "limegreen",50,205,50, 255 },
-        { "linen",250,240,230, 255 },
-        { "magenta",255,0,255, 255 },
-        { "maroon",128,0,0, 255 },
-        { "mediumaquamarine",102,205,170, 255 },
-        { "mediumblue",0,0,205, 255 },
-        { "mediumorchid",186,85,211, 255 },
-        { "mediumpurple",147,112,219, 255 },
-        { "mediumseagreen",60,179,113, 255 },
-        { "mediumslateblue",123,104,238, 255 },
-        { "mediumspringgreen",0,250,154, 255 },
-        { "mediumturquoise",72,209,204, 255 },
-        { "mediumvioletred",199,21,133, 255 },
-        { "midnightblue",25,25,112, 255 },
-        { "mintcream",245,255,250, 255 },
-        { "mistyrose",255,228,225, 255 },
-        { "moccasin",255,228,181, 255 },
-        { "navajowhite",255,222,173, 255 },
-        { "navy",0,0,128, 255 },
-        { "oldlace",253,245,230, 255 },
-        { "olive",128,128,0, 255 },
-        { "olivedrab",107,142,35, 255 },
-        { "orange",255,165,0, 255 },
-        { "orangered",255,69,0, 255 },
-        { "orchid",218,112,214, 255 },
-        { "palegoldenrod",238,232,170, 255 },
-        { "palegreen",152,251,152, 255 },
-        { "paleturquoise",175,238,238, 255 },
-        { "palevioletred",219,112,147, 255 },
-        { "papayawhip",255,239,213, 255 },
-        { "peachpuff",255,218,185, 255 },
-        { "peru",205,133,63, 255 },
-        { "pink",255,192,203, 255 },
-        { "plum",221,160,221, 255 },
-        { "powderblue",176,224,230, 255 },
-        { "purple",128,0,128, 255 },
-        { "red",255,0,0, 255 },
-        { "rosybrown",188,143,143, 255 },
-        { "royalblue",65,105,225, 255 },
-        { "saddlebrown",139,69,19, 255 },
-        { "salmon",250,128,114, 255 },
-        { "sandybrown",244,164,96, 255 },
-        { "seagreen",46,139,87, 255 },
-        { "seashell",255,245,238, 255 },
-        { "sienna",160,82,45, 255 },
-        { "silver",192,192,192, 255 },
-        { "skyblue",135,206,235, 255 },
-        { "slateblue",106,90,205, 255 },
-        { "slategray",112,128,144, 255 },
-        { "slategrey",112,128,144, 255 },
-        { "snow",255,250,250, 255 },
-        { "springgreen",0,255,127, 255 },
-        { "steelblue",70,130,180, 255 },
-        { "tan",210,180,140, 255 },
-        { "teal",0,128,128, 255 },
-        { "thistle",216,191,216, 255 },
-        { "tomato",255,99,71, 255 },
-        { "turquoise",64,224,208, 255 },
-        { "violet",238,130,238, 255 },
-        { "wheat",245,222,179, 255 },
-        { "white",255,255,255, 255 },
-        { "whitesmoke",245,245,245, 255 },
-        { "yellow",255,255,0, 255 },
-        { "yellowgreen",154,205,50, 255 },
-        { "zzzzzzzzzzz",0,0,0, 0 }
-    }; 
-
-
-    //------------------------------------------------------------------------
-    parser::~parser()
-    {
-        delete [] m_attr_value;
-        delete [] m_attr_name;
-        delete [] m_buf;
-        delete [] m_title;
-    }
-
-    //------------------------------------------------------------------------
-    parser::parser(path_renderer& path) :
-        m_path(path),
-        m_tokenizer(),
-        m_buf(new char[buf_size]),
-        m_title(new char[256]),
-        m_title_len(0),
-        m_title_flag(false),
-        m_path_flag(false),
-        m_attr_name(new char[128]),
-        m_attr_value(new char[1024]),
-        m_attr_name_len(127),
-        m_attr_value_len(1023)
-    {
-        m_title[0] = 0;
-    }
-
-    //------------------------------------------------------------------------
-    void parser::parse(const char* fname)
-    {
-        char msg[1024];
-	    XML_Parser p = XML_ParserCreate(NULL);
-	    if(p == 0) 
-	    {
-		    throw exception("Couldn't allocate memory for parser");
-	    }
-
-        XML_SetUserData(p, this);
-	    XML_SetElementHandler(p, start_element, end_element);
-	    XML_SetCharacterDataHandler(p, content);
-
-        FILE* fd = fopen(fname, "r");
-        if(fd == 0)
-        {
-            sprintf(msg, "Couldn't open file %s", fname);
-		    throw exception(msg);
-        }
-
-        bool done = false;
-        do
-        {
-            size_t len = fread(m_buf, 1, buf_size, fd);
-            done = len < buf_size;
-            if(!XML_Parse(p, m_buf, len, done))
-            {
-                sprintf(msg,
-                    "%s at line %d\n",
-                    XML_ErrorString(XML_GetErrorCode(p)),
-                    XML_GetCurrentLineNumber(p));
-                throw exception(msg);
-            }
-        }
-        while(!done);
-        fclose(fd);
-        XML_ParserFree(p);
-
-        char* ts = m_title;
-        while(*ts)
-        {
-            if(*ts < ' ') *ts = ' ';
-            ++ts;
-        }
-    }
-
-
-    //------------------------------------------------------------------------
-    void parser::start_element(void* data, const char* el, const char** attr)
-    {
-        parser& self = *(parser*)data;
-
-        if(strcmp(el, "title") == 0)
-        {
-            self.m_title_flag = true;
-        }
-        else
-        if(strcmp(el, "g") == 0)
-        {
-            self.m_path.push_attr();
-            self.parse_attr(attr);
-        }
-        else
-        if(strcmp(el, "path") == 0)
-        {
-            if(self.m_path_flag)
-            {
-                throw exception("start_element: Nested path");
-            }
-            self.m_path.begin_path();
-            self.parse_path(attr);
-            self.m_path.end_path();
-            self.m_path_flag = true;
-        }
-        else
-        if(strcmp(el, "rect") == 0) 
-        {
-            self.parse_rect(attr);
-        }
-        else
-        if(strcmp(el, "line") == 0) 
-        {
-            self.parse_line(attr);
-        }
-        else
-        if(strcmp(el, "polyline") == 0) 
-        {
-            self.parse_poly(attr, false);
-        }
-        else
-        if(strcmp(el, "polygon") == 0) 
-        {
-            self.parse_poly(attr, true);
-        }
-        //else
-        //if(strcmp(el, "<OTHER_ELEMENTS>") == 0) 
-        //{
-        //}
-        // . . .
-    } 
-
-
-    //------------------------------------------------------------------------
-    void parser::end_element(void* data, const char* el)
-    {
-        parser& self = *(parser*)data;
-
-        if(strcmp(el, "title") == 0)
-        {
-            self.m_title_flag = false;
-        }
-        else
-        if(strcmp(el, "g") == 0)
-        {
-            self.m_path.pop_attr();
-        }
-        else
-        if(strcmp(el, "path") == 0)
-        {
-            self.m_path_flag = false;
-        }
-        //else
-        //if(strcmp(el, "<OTHER_ELEMENTS>") == 0) 
-        //{
-        //}
-        // . . .
-    }
-
-
-    //------------------------------------------------------------------------
-    void parser::content(void* data, const char* s, int len)
-    {
-        parser& self = *(parser*)data;
-
-        // m_title_flag signals that the <title> tag is being parsed now.
-        // The following code concatenates the pieces of content of the <title> tag.
-        if(self.m_title_flag)
-        {
-            if(len + self.m_title_len > 255) len = 255 - self.m_title_len;
-            if(len > 0) 
-            {
-                memcpy(self.m_title + self.m_title_len, s, len);
-                self.m_title_len += len;
-                self.m_title[self.m_title_len] = 0;
-            }
-        }
-    }
-
-
-    //------------------------------------------------------------------------
-    void parser::parse_attr(const char** attr)
-    {
-        int i;
-        for(i = 0; attr[i]; i += 2)
-        {
-            if(strcmp(attr[i], "style") == 0)
-            {
-                parse_style(attr[i + 1]);
-            }
-            else
-            {
-                parse_attr(attr[i], attr[i + 1]);
-            }
-        }
-    }
-
-    //-------------------------------------------------------------
-    void parser::parse_path(const char** attr)
-    {
-        int i;
-
-        for(i = 0; attr[i]; i += 2)
-        {
-            // The <path> tag can consist of the path itself ("d=") 
-            // as well as of other parameters like "style=", "transform=", etc.
-            // In the last case we simply rely on the function of parsing 
-            // attributes (see 'else' branch).
-            if(strcmp(attr[i], "d") == 0)
-            {
-                m_tokenizer.set_path_str(attr[i + 1]);
-                m_path.parse_path(m_tokenizer);
-            }
-            else
-            {
-                // Create a temporary single pair "name-value" in order
-                // to avoid multiple calls for the same attribute.
-                const char* tmp[4];
-                tmp[0] = attr[i];
-                tmp[1] = attr[i + 1];
-                tmp[2] = 0;
-                tmp[3] = 0;
-                parse_attr(tmp);
-            }
-        }
-    }
-
-
-    //-------------------------------------------------------------
-    int cmp_color(const void* p1, const void* p2)
-    {
-        return strcmp(((named_color*)p1)->name, ((named_color*)p2)->name);
-    }
-
-    //-------------------------------------------------------------
-    rgba8 parse_color(const char* str)
-    {
-        while(*str == ' ') ++str;
-        unsigned c = 0;
-        if(*str == '#')
-        {
-            sscanf(str + 1, "%x", &c);
-            return rgb8_packed(c);
-        }
-        else
-        {
-            named_color c;
-            unsigned len = strlen(str);
-            if(len > sizeof(c.name) - 1)
-            {
-                throw exception("parse_color: Invalid color name '%s'", str);
-            }
-            strcpy(c.name, str);
-            const void* p = bsearch(&c, 
-                                    colors, 
-                                    sizeof(colors) / sizeof(colors[0]), 
-                                    sizeof(colors[0]), 
-                                    cmp_color);
-            if(p == 0)
-            {
-                throw exception("parse_color: Invalid color name '%s'", str);
-            }
-            const named_color* pc = (const named_color*)p;
-            return rgba8(pc->r, pc->g, pc->b, pc->a);
-        }
-    }
-
-    double parse_double(const char* str)
-    {
-        while(*str == ' ') ++str;
-        return atof(str);
-    }
-
-
-
-    //-------------------------------------------------------------
-    bool parser::parse_attr(const char* name, const char* value)
-    {
-        if(strcmp(name, "style") == 0)
-        {
-            parse_style(value);
-        }
-        else
-        if(strcmp(name, "fill") == 0)
-        {
-            if(strcmp(value, "none") == 0)
-            {
-                m_path.fill_none();
-            }
-            else
-            {
-                m_path.fill(parse_color(value));
-            }
-        }
-        else
-        if(strcmp(name, "fill-opacity") == 0)
-        {
-            m_path.fill_opacity(parse_double(value));
-        }
-        else
-        if(strcmp(name, "stroke") == 0)
-        {
-            if(strcmp(value, "none") == 0)
-            {
-                m_path.stroke_none();
-            }
-            else
-            {
-                m_path.stroke(parse_color(value));
-            }
-        }
-        else
-        if(strcmp(name, "stroke-width") == 0)
-        {
-            m_path.stroke_width(parse_double(value));
-        }
-        else
-        if(strcmp(name, "stroke-linecap") == 0)
-        {
-            if(strcmp(value, "butt") == 0)        m_path.line_cap(butt_cap);
-            else if(strcmp(value, "round") == 0)  m_path.line_cap(round_cap);
-            else if(strcmp(value, "square") == 0) m_path.line_cap(square_cap);
-        }
-        else
-        if(strcmp(name, "stroke-linejoin") == 0)
-        {
-            if(strcmp(value, "miter") == 0)      m_path.line_join(miter_join);
-            else if(strcmp(value, "round") == 0) m_path.line_join(round_join);
-            else if(strcmp(value, "bevel") == 0) m_path.line_join(bevel_join);
-        }
-        else
-        if(strcmp(name, "stroke-miterlimit") == 0)
-        {
-            m_path.miter_limit(parse_double(value));
-        }
-        else
-        if(strcmp(name, "stroke-opacity") == 0)
-        {
-            m_path.stroke_opacity(parse_double(value));
-        }
-        else
-        if(strcmp(name, "transform") == 0)
-        {
-            parse_transform(value);
-        }
-        //else
-        //if(strcmp(el, "<OTHER_ATTRIBUTES>") == 0) 
-        //{
-        //}
-        // . . .
-        else
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-
-    //-------------------------------------------------------------
-    void parser::copy_name(const char* start, const char* end)
-    {
-        unsigned len = unsigned(end - start);
-        if(m_attr_name_len == 0 || len > m_attr_name_len)
-        {
-            delete [] m_attr_name;
-            m_attr_name = new char[len + 1];
-            m_attr_name_len = len;
-        }
-        if(len) memcpy(m_attr_name, start, len);
-        m_attr_name[len] = 0;
-    }
-
-
-
-    //-------------------------------------------------------------
-    void parser::copy_value(const char* start, const char* end)
-    {
-        unsigned len = unsigned(end - start);
-        if(m_attr_value_len == 0 || len > m_attr_value_len)
-        {
-            delete [] m_attr_value;
-            m_attr_value = new char[len + 1];
-            m_attr_value_len = len;
-        }
-        if(len) memcpy(m_attr_value, start, len);
-        m_attr_value[len] = 0;
-    }
-
-
-    //-------------------------------------------------------------
-    bool parser::parse_name_value(const char* nv_start, const char* nv_end)
-    {
-        const char* str = nv_start;
-        while(str < nv_end && *str != ':') ++str;
-
-        const char* val = str;
-
-        // Right Trim
-        while(str > nv_start && 
-            (*str == ':' || isspace(*str))) --str;
-        ++str;
-
-        copy_name(nv_start, str);
-
-        while(val < nv_end && (*val == ':' || isspace(*val))) ++val;
-        
-        copy_value(val, nv_end);
-        return parse_attr(m_attr_name, m_attr_value);
-    }
-
-
-
-    //-------------------------------------------------------------
-    void parser::parse_style(const char* str)
-    {
-        while(*str)
-        {
-            // Left Trim
-            while(*str && isspace(*str)) ++str;
-            const char* nv_start = str;
-            while(*str && *str != ';') ++str;
-            const char* nv_end = str;
-
-            // Right Trim
-            while(nv_end > nv_start && 
-                (*nv_end == ';' || isspace(*nv_end))) --nv_end;
-            ++nv_end;
-
-            parse_name_value(nv_start, nv_end);
-            if(*str) ++str;
-        }
-
-    }
-
-
-    //-------------------------------------------------------------
-    void parser::parse_rect(const char** attr)
-    {
-        int i;
-        double x = 0.0;
-        double y = 0.0;
-        double w = 0.0;
-        double h = 0.0;
-
-        m_path.begin_path();
-        for(i = 0; attr[i]; i += 2)
-        {
-            if(!parse_attr(attr[i], attr[i + 1]))
-            {
-                if(strcmp(attr[i], "x") == 0)      x = parse_double(attr[i + 1]);
-                if(strcmp(attr[i], "y") == 0)      y = parse_double(attr[i + 1]);
-                if(strcmp(attr[i], "width") == 0)  w = parse_double(attr[i + 1]);
-                if(strcmp(attr[i], "height") == 0) h = parse_double(attr[i + 1]);
-                // rx - to be implemented 
-                // ry - to be implemented
-            }
-        }
-
-
-        if(w != 0.0 && h != 0.0)
-        {
-            if(w < 0.0) throw exception("parse_rect: Invalid width: %f", w);
-            if(h < 0.0) throw exception("parse_rect: Invalid height: %f", h);
-
-            m_path.move_to(x,     y);
-            m_path.line_to(x + w, y);
-            m_path.line_to(x + w, y + h);
-            m_path.line_to(x,     y + h);
-            m_path.close_subpath();
-        }
-        m_path.end_path();
-    }
-
-
-    //-------------------------------------------------------------
-    void parser::parse_line(const char** attr)
-    {
-        int i;
-        double x1 = 0.0;
-        double y1 = 0.0;
-        double x2 = 0.0;
-        double y2 = 0.0;
-
-        m_path.begin_path();
-        for(i = 0; attr[i]; i += 2)
-        {
-            if(!parse_attr(attr[i], attr[i + 1]))
-            {
-                if(strcmp(attr[i], "x1") == 0) x1 = parse_double(attr[i + 1]);
-                if(strcmp(attr[i], "y1") == 0) y1 = parse_double(attr[i + 1]);
-                if(strcmp(attr[i], "x2") == 0) x2 = parse_double(attr[i + 1]);
-                if(strcmp(attr[i], "y2") == 0) y2 = parse_double(attr[i + 1]);
-            }
-        }
-
-        m_path.move_to(x1, y1);
-        m_path.line_to(x2, y2);
-        m_path.end_path();
-    }
-
-
-    //-------------------------------------------------------------
-    void parser::parse_poly(const char** attr, bool close_flag)
-    {
-        int i;
-        double x = 0.0;
-        double y = 0.0;
-
-        m_path.begin_path();
-        for(i = 0; attr[i]; i += 2)
-        {
-            if(!parse_attr(attr[i], attr[i + 1]))
-            {
-                if(strcmp(attr[i], "points") == 0) 
-                {
-                    m_tokenizer.set_path_str(attr[i + 1]);
-                    if(!m_tokenizer.next())
-                    {
-                        throw exception("parse_poly: Too few coordinates");
-                    }
-                    x = m_tokenizer.last_number();
-                    if(!m_tokenizer.next())
-                    {
-                        throw exception("parse_poly: Too few coordinates");
-                    }
-                    y = m_tokenizer.last_number();
-                    m_path.move_to(x, y);
-                    while(m_tokenizer.next())
-                    {
-                        x = m_tokenizer.last_number();
-                        if(!m_tokenizer.next())
-                        {
-                            throw exception("parse_poly: Odd number of coordinates");
-                        }
-                        y = m_tokenizer.last_number();
-                        m_path.line_to(x, y);
-                    }
-                }
-            }
-        }
-        if(close_flag) 
-        {
-            m_path.close_subpath();
-        }
-        m_path.end_path();
-    }
-
-    //-------------------------------------------------------------
-    void parser::parse_transform(const char* str)
-    {
-        while(*str)
-        {
-            if(islower(*str))
-            {
-                if(strncmp(str, "matrix", 6) == 0)    str += parse_matrix(str);    else 
-                if(strncmp(str, "translate", 9) == 0) str += parse_translate(str); else 
-                if(strncmp(str, "rotate", 6) == 0)    str += parse_rotate(str);    else 
-                if(strncmp(str, "scale", 5) == 0)     str += parse_scale(str);     else 
-                if(strncmp(str, "skewX", 5) == 0)     str += parse_skew_x(str);    else 
-                if(strncmp(str, "skewY", 5) == 0)     str += parse_skew_y(str);    else
-                {
-                    ++str;
-                }
-            }
-            else
-            {
-                ++str;
-            }
-        }
-    }
-
-
-    //-------------------------------------------------------------
-    static bool is_numeric(char c)
-    {
-        return strchr("0123456789+-.eE", c) != 0;
-    }
-
-    //-------------------------------------------------------------
-    static unsigned parse_transform_args(const char* str, 
-                                         double* args, 
-                                         unsigned max_na, 
-                                         unsigned* na)
-    {
-        *na = 0;
-        const char* ptr = str;
-        while(*ptr && *ptr != '(') ++ptr;
-        if(*ptr == 0)
-        {
-            throw exception("parse_transform_args: Invalid syntax");
-        }
-        const char* end = ptr;
-        while(*end && *end != ')') ++end;
-        if(*end == 0)
-        {
-            throw exception("parse_transform_args: Invalid syntax");
-        }
-
-        while(ptr < end)
-        {
-            if(is_numeric(*ptr))
-            {
-                if(*na >= max_na)
-                {
-                    throw exception("parse_transform_args: Too many arguments");
-                }
-                args[(*na)++] = atof(ptr);
-                while(ptr < end && is_numeric(*ptr)) ++ptr;
-            }
-            else
-            {
-                ++ptr;
-            }
-        }
-        return unsigned(end - str);
-    }
-
-    //-------------------------------------------------------------
-    unsigned parser::parse_matrix(const char* str)
-    {
-        double args[6];
-        unsigned na = 0;
-        unsigned len = parse_transform_args(str, args, 6, &na);
-        if(na != 6)
-        {
-            throw exception("parse_matrix: Invalid number of arguments");
-        }
-        m_path.transform().premultiply(trans_affine(args[0], args[1], args[2], args[3], args[4], args[5]));
-        return len;
-    }
-
-    //-------------------------------------------------------------
-    unsigned parser::parse_translate(const char* str)
-    {
-        double args[2];
-        unsigned na = 0;
-        unsigned len = parse_transform_args(str, args, 2, &na);
-        if(na == 1) args[1] = 0.0;
-        m_path.transform().premultiply(trans_affine_translation(args[0], args[1]));
-        return len;
-    }
-
-    //-------------------------------------------------------------
-    unsigned parser::parse_rotate(const char* str)
-    {
-        double args[3];
-        unsigned na = 0;
-        unsigned len = parse_transform_args(str, args, 3, &na);
-        if(na == 1) 
-        {
-            m_path.transform().premultiply(trans_affine_rotation(deg2rad(args[0])));
-        }
-        else if(na == 3)
-        {
-            trans_affine t = trans_affine_translation(-args[1], -args[2]);
-            t *= trans_affine_rotation(deg2rad(args[0]));
-            t *= trans_affine_translation(args[1], args[2]);
-            m_path.transform().premultiply(t);
-        }
-        else
-        {
-            throw exception("parse_rotate: Invalid number of arguments");
-        }
-        return len;
-    }
-
-    //-------------------------------------------------------------
-    unsigned parser::parse_scale(const char* str)
-    {
-        double args[2];
-        unsigned na = 0;
-        unsigned len = parse_transform_args(str, args, 2, &na);
-        if(na == 1) args[1] = args[0];
-        m_path.transform().premultiply(trans_affine_scaling(args[0], args[1]));
-        return len;
-    }
-
-    //-------------------------------------------------------------
-    unsigned parser::parse_skew_x(const char* str)
-    {
-        double arg;
-        unsigned na = 0;
-        unsigned len = parse_transform_args(str, &arg, 1, &na);
-        m_path.transform().premultiply(trans_affine_skewing(deg2rad(arg), 0.0));
-        return len;
-    }
-
-    //-------------------------------------------------------------
-    unsigned parser::parse_skew_y(const char* str)
-    {
-        double arg;
-        unsigned na = 0;
-        unsigned len = parse_transform_args(str, &arg, 1, &na);
-        m_path.transform().premultiply(trans_affine_skewing(0.0, deg2rad(arg)));
-        return len;
-    }
-
-}
-}
-
-
diff --git a/src/agg_svg/agg_svg_parser.h b/src/agg_svg/agg_svg_parser.h
deleted file mode 100644
index 4d40936c7..000000000
--- a/src/agg_svg/agg_svg_parser.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software 
-// is granted provided this copyright notice appears in all copies. 
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// SVG parser.
-//
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SVG_PARSER_INCLUDED
-#define AGG_SVG_PARSER_INCLUDED
-
-#include "agg_svg_path_tokenizer.h"
-#include "agg_svg_path_renderer.h"
-
-namespace agg
-{
-namespace svg
-{
-
-    class parser
-    {
-        enum buf_size_e { buf_size = BUFSIZ };
-    public:
-
-        ~parser();
-        parser(path_renderer& path);
-
-        void parse(const char* fname);
-        const char* title() const { return m_title; }
-
-    private:
-        // XML event handlers
-        static void start_element(void* data, const char* el, const char** attr);
-        static void end_element(void* data, const char* el);
-        static void content(void* data, const char* s, int len);
-
-        void parse_attr(const char** attr);
-        void parse_path(const char** attr);
-        void parse_poly(const char** attr, bool close_flag);
-        void parse_rect(const char** attr);
-        void parse_line(const char** attr);
-        void parse_style(const char* str);
-        void parse_transform(const char* str);
-
-        unsigned parse_matrix(const char* str);
-        unsigned parse_translate(const char* str);
-        unsigned parse_rotate(const char* str);
-        unsigned parse_scale(const char* str);
-        unsigned parse_skew_x(const char* str);
-        unsigned parse_skew_y(const char* str);
-        
-        bool parse_attr(const char* name, const char* value);
-        bool parse_name_value(const char* nv_start, const char* nv_end);
-        void copy_name(const char* start, const char* end);
-        void copy_value(const char* start, const char* end);
-        
-    private:
-        path_renderer& m_path;
-        path_tokenizer m_tokenizer;
-        char*          m_buf;
-        char*          m_title;
-        unsigned       m_title_len;
-        bool           m_title_flag;
-        bool           m_path_flag;
-        char*          m_attr_name;
-        char*          m_attr_value;
-        unsigned       m_attr_name_len;
-        unsigned       m_attr_value_len;
-    };
-
-}
-}
-
-#endif
diff --git a/src/agg_svg/agg_svg_path_renderer.cpp b/src/agg_svg/agg_svg_path_renderer.cpp
deleted file mode 100644
index 27c7b2e3a..000000000
--- a/src/agg_svg/agg_svg_path_renderer.cpp
+++ /dev/null
@@ -1,366 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software 
-// is granted provided this copyright notice appears in all copies. 
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// SVG path renderer.
-//
-//----------------------------------------------------------------------------
-
-#include <stdio.h>
-#include "agg_svg_path_renderer.h"
-
-namespace agg
-{
-namespace svg
-{
-
-    //------------------------------------------------------------------------
-    path_renderer::path_renderer() :
-        m_curved(m_storage),
-        m_curved_count(m_curved),
-
-        m_curved_stroked(m_curved_count),
-        m_curved_stroked_trans(m_curved_stroked, m_transform),
-
-        m_curved_trans(m_curved_count, m_transform),
-        m_curved_trans_contour(m_curved_trans)
-    {
-        m_curved_trans_contour.auto_detect_orientation(false);
-    }
-
-
-    //------------------------------------------------------------------------
-    void path_renderer::remove_all()
-    {
-        m_storage.remove_all();
-        m_attr_storage.remove_all();
-        m_attr_stack.remove_all();
-        m_transform.reset();
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::begin_path()
-    {
-        push_attr();
-        unsigned idx = m_storage.start_new_path();
-        m_attr_storage.add(path_attributes(cur_attr(), idx));
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::end_path()
-    {
-        if(m_attr_storage.size() == 0) 
-        {
-            throw exception("end_path : The path was not begun");
-        }
-        path_attributes attr = cur_attr();
-        unsigned idx = m_attr_storage[m_attr_storage.size() - 1].index;
-        attr.index = idx;
-        m_attr_storage[m_attr_storage.size() - 1] = attr;
-        pop_attr();
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::move_to(double x, double y, bool rel)          // M, m
-    {
-        if(rel) m_storage.rel_to_abs(&x, &y);
-        m_storage.move_to(x, y);
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::line_to(double x,  double y, bool rel)         // L, l
-    {
-        if(rel) m_storage.rel_to_abs(&x, &y);
-        m_storage.line_to(x, y);
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::hline_to(double x, bool rel)                   // H, h
-    {
-        double x2 = 0.0;
-        double y2 = 0.0;
-        if(m_storage.total_vertices())
-        {
-            m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2);
-            if(rel) x += x2;
-            m_storage.line_to(x, y2);
-        }
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::vline_to(double y, bool rel)                   // V, v
-    {
-        double x2 = 0.0;
-        double y2 = 0.0;
-        if(m_storage.total_vertices())
-        {
-            m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2);
-            if(rel) y += y2;
-            m_storage.line_to(x2, y);
-        }
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::curve3(double x1, double y1,                   // Q, q
-                               double x,  double y, bool rel)
-    {
-        if(rel) 
-        {
-            m_storage.rel_to_abs(&x1, &y1);
-            m_storage.rel_to_abs(&x,  &y);
-        }
-        m_storage.curve3(x1, y1, x, y);
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::curve3(double x, double y, bool rel)           // T, t
-    {
-//        throw exception("curve3(x, y) : NOT IMPLEMENTED YET");
-        if(rel) 
-        {
-            m_storage.curve3_rel(x, y);
-        } else 
-        {
-            m_storage.curve3(x, y);
-        }
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::curve4(double x1, double y1,                   // C, c
-                               double x2, double y2, 
-                               double x,  double y, bool rel)
-    {
-        if(rel) 
-        {
-            m_storage.rel_to_abs(&x1, &y1);
-            m_storage.rel_to_abs(&x2, &y2);
-            m_storage.rel_to_abs(&x,  &y);
-        }
-        m_storage.curve4(x1, y1, x2, y2, x, y);
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::curve4(double x2, double y2,                   // S, s
-                               double x,  double y, bool rel)
-    {
-        //throw exception("curve4(x2, y2, x, y) : NOT IMPLEMENTED YET");
-        if(rel) 
-        {
-            m_storage.curve4_rel(x2, y2, x, y);
-        } else 
-        {
-            m_storage.curve4(x2, y2, x, y);
-        }
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::close_subpath()
-    {
-        m_storage.end_poly(path_flags_close);
-    }
-
-    //------------------------------------------------------------------------
-    path_attributes& path_renderer::cur_attr()
-    {
-        if(m_attr_stack.size() == 0)
-        {
-            throw exception("cur_attr : Attribute stack is empty");
-        }
-        return m_attr_stack[m_attr_stack.size() - 1];
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::push_attr()
-    {
-        m_attr_stack.add(m_attr_stack.size() ? 
-                         m_attr_stack[m_attr_stack.size() - 1] :
-                         path_attributes());
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::pop_attr()
-    {
-        if(m_attr_stack.size() == 0)
-        {
-            throw exception("pop_attr : Attribute stack is empty");
-        }
-        m_attr_stack.remove_last();
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::fill(const rgba8& f)
-    {
-        path_attributes& attr = cur_attr();
-        attr.fill_color = f;
-        attr.fill_flag = true;
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::stroke(const rgba8& s)
-    {
-        path_attributes& attr = cur_attr();
-        attr.stroke_color = s;
-        attr.stroke_flag = true;
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::even_odd(bool flag)
-    {
-        cur_attr().even_odd_flag = flag;
-    }
-    
-    //------------------------------------------------------------------------
-    void path_renderer::stroke_width(double w)
-    {
-        cur_attr().stroke_width = w;
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::fill_none()
-    {
-        cur_attr().fill_flag = false;
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::stroke_none()
-    {
-        cur_attr().stroke_flag = false;
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::fill_opacity(double op)
-    {
-        cur_attr().fill_color.opacity(op);
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::stroke_opacity(double op)
-    {
-        cur_attr().stroke_color.opacity(op);
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::line_join(line_join_e join)
-    {
-        cur_attr().line_join = join;
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::line_cap(line_cap_e cap)
-    {
-        cur_attr().line_cap = cap;
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::miter_limit(double ml)
-    {
-        cur_attr().miter_limit = ml;
-    }
-
-    //------------------------------------------------------------------------
-    trans_affine& path_renderer::transform()
-    {
-        return cur_attr().transform;
-    }
-
-    //------------------------------------------------------------------------
-    void path_renderer::parse_path(path_tokenizer& tok)
-    {
-        while(tok.next())
-        {
-            double arg[10];
-            char cmd = tok.last_command();
-            unsigned i;
-            switch(cmd)
-            {
-                case 'M': case 'm':
-                    arg[0] = tok.last_number();
-                    arg[1] = tok.next(cmd);
-                    move_to(arg[0], arg[1], cmd == 'm');
-                    break;
-
-                case 'L': case 'l':
-                    arg[0] = tok.last_number();
-                    arg[1] = tok.next(cmd);
-                    line_to(arg[0], arg[1], cmd == 'l');
-                    break;
-
-                case 'V': case 'v':
-                    vline_to(tok.last_number(), cmd == 'v');
-                    break;
-
-                case 'H': case 'h':
-                    hline_to(tok.last_number(), cmd == 'h');
-                    break;
-                
-                case 'Q': case 'q':
-                    arg[0] = tok.last_number();
-                    for(i = 1; i < 4; i++)
-                    {
-                        arg[i] = tok.next(cmd);
-                    }
-                    curve3(arg[0], arg[1], arg[2], arg[3], cmd == 'q');
-                    break;
-
-                case 'T': case 't':
-                    arg[0] = tok.last_number();
-                    arg[1] = tok.next(cmd);
-                    curve3(arg[0], arg[1], cmd == 't');
-                    break;
-
-                case 'C': case 'c':
-                    arg[0] = tok.last_number();
-                    for(i = 1; i < 6; i++)
-                    {
-                        arg[i] = tok.next(cmd);
-                    }
-                    curve4(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], cmd == 'c');
-                    break;
-
-                case 'S': case 's':
-                    arg[0] = tok.last_number();
-                    for(i = 1; i < 4; i++)
-                    {
-                        arg[i] = tok.next(cmd);
-                    }
-                    curve4(arg[0], arg[1], arg[2], arg[3], cmd == 's');
-                    break;
-
-                case 'A': case 'a':
-					arg[0] = tok.last_number();
-					for (i = 1; i < 7; i++)
-					{
-						arg[i] = tok.next(cmd);
-					}
-//					curve3(arg[0], arg[1], arg[2], arg[3], cmd == 'q');
-//                    throw exception("parse_path: Command A: NOT IMPLEMENTED YET");
-					break;
-
-                case 'Z': case 'z':
-                    close_subpath();
-                    break;
-
-                default:
-                {
-                    char buf[100];
-                    sprintf(buf, "parse_path: Invalid Command %c", cmd);
-                    throw exception(buf);
-                }
-            }
-        }
-    }
-
-}
-}
-
diff --git a/src/agg_svg/agg_svg_path_renderer.h b/src/agg_svg/agg_svg_path_renderer.h
deleted file mode 100644
index 0f27066b5..000000000
--- a/src/agg_svg/agg_svg_path_renderer.h
+++ /dev/null
@@ -1,321 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software 
-// is granted provided this copyright notice appears in all copies. 
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// SVG path renderer.
-//
-//----------------------------------------------------------------------------
-#ifndef AGG_SVG_PATH_RENDERER_INCLUDED
-#define AGG_SVG_PATH_RENDERER_INCLUDED
-
-#include <agg/agg_path_storage.h>
-#include <agg/agg_conv_transform.h>
-#include <agg/agg_conv_stroke.h>
-#include <agg/agg_conv_contour.h>
-#include <agg/agg_conv_curve.h>
-#include <agg/agg_color_rgba.h>
-#include <agg/agg_renderer_scanline.h>
-#include <agg/agg_bounding_rect.h>
-#include <agg/agg_rasterizer_scanline_aa.h>
-#include "agg_svg_path_tokenizer.h"
-
-namespace agg
-{
-namespace svg
-{
-    template<class VertexSource> class conv_count
-    {
-    public:
-        conv_count(VertexSource& vs) : m_source(&vs), m_count(0) {}
-
-        void count(unsigned n) { m_count = n; }
-        unsigned count() const { return m_count; }
-
-        void rewind(unsigned path_id) { m_source->rewind(path_id); }
-        unsigned vertex(double* x, double* y) 
-        { 
-            ++m_count; 
-            return m_source->vertex(x, y); 
-        }
-
-    private:
-        VertexSource* m_source;
-        unsigned m_count;
-    };
-
-
-
-
-    //============================================================================
-    // Basic path attributes
-    struct path_attributes
-    {
-        unsigned     index;
-        rgba8        fill_color;
-        rgba8        stroke_color;
-        bool         fill_flag;
-        bool         stroke_flag;
-        bool         even_odd_flag;
-        line_join_e  line_join;
-        line_cap_e   line_cap;
-        double       miter_limit;
-        double       stroke_width;
-        trans_affine transform;
-
-        // Empty constructor
-        path_attributes() :
-            index(0),
-            fill_color(rgba(0,0,0)),
-            stroke_color(rgba(0,0,0)),
-            fill_flag(true),
-            stroke_flag(false),
-            even_odd_flag(false),
-            line_join(miter_join),
-            line_cap(butt_cap),
-            miter_limit(4.0),
-            stroke_width(1.0),
-            transform()
-        {
-        }
-
-        // Copy constructor
-        path_attributes(const path_attributes& attr) :
-            index(attr.index),
-            fill_color(attr.fill_color),
-            stroke_color(attr.stroke_color),
-            fill_flag(attr.fill_flag),
-            stroke_flag(attr.stroke_flag),
-            even_odd_flag(attr.even_odd_flag),
-            line_join(attr.line_join),
-            line_cap(attr.line_cap),
-            miter_limit(attr.miter_limit),
-            stroke_width(attr.stroke_width),
-            transform(attr.transform)
-        {
-        }
-
-        // Copy constructor with new index value
-        path_attributes(const path_attributes& attr, unsigned idx) :
-            index(idx),
-            fill_color(attr.fill_color),
-            stroke_color(attr.stroke_color),
-            fill_flag(attr.fill_flag),
-            stroke_flag(attr.stroke_flag),
-            even_odd_flag(attr.even_odd_flag),
-            line_join(attr.line_join),
-            line_cap(attr.line_cap),
-            miter_limit(attr.miter_limit),
-            stroke_width(attr.stroke_width),
-            transform(attr.transform)
-        {
-        }
-    };
-
-
-    //============================================================================
-    // Path container and renderer. 
-    class path_renderer
-    {
-    public:
-        typedef pod_bvector<path_attributes>   attr_storage;
-
-        typedef conv_curve<path_storage>       curved;
-        typedef conv_count<curved>             curved_count;
-
-        typedef conv_stroke<curved_count>      curved_stroked;
-        typedef conv_transform<curved_stroked> curved_stroked_trans;
-
-        typedef conv_transform<curved_count>   curved_trans;
-        typedef conv_contour<curved_trans>     curved_trans_contour;
-
-        path_renderer();
-
-        void remove_all();
-
-        // Use these functions as follows:
-        // begin_path() when the XML tag <path> comes ("start_element" handler)
-        // parse_path() on "d=" tag attribute
-        // end_path() when parsing of the entire tag is done.
-        void begin_path();
-        void parse_path(path_tokenizer& tok);
-        void end_path();
-
-        // The following functions are essentially a "reflection" of
-        // the respective SVG path commands.
-        void move_to(double x, double y, bool rel=false);   // M, m
-        void line_to(double x,  double y, bool rel=false);  // L, l
-        void hline_to(double x, bool rel=false);            // H, h
-        void vline_to(double y, bool rel=false);            // V, v
-        void curve3(double x1, double y1,                   // Q, q
-                    double x,  double y, bool rel=false);
-        void curve3(double x, double y, bool rel=false);    // T, t
-        void curve4(double x1, double y1,                   // C, c
-                    double x2, double y2, 
-                    double x,  double y, bool rel=false);
-        void curve4(double x2, double y2,                   // S, s
-                    double x,  double y, bool rel=false);
-        void close_subpath();                               // Z, z
-
-//        template<class VertexSource> 
-//        void add_path(VertexSource& vs, 
-//                      unsigned path_id = 0, 
-//                      bool solid_path = true)
-//        {
-//            m_storage.add_path(vs, path_id, solid_path);
-//        }
-
-
-        unsigned vertex_count() const { return m_curved_count.count(); }
-        
-
-        // Call these functions on <g> tag (start_element, end_element respectively)
-        void push_attr();
-        void pop_attr();
-
-        // Attribute setting functions.
-        void fill(const rgba8& f);
-        void stroke(const rgba8& s);
-        void even_odd(bool flag);
-        void stroke_width(double w);
-        void fill_none();
-        void stroke_none();
-        void fill_opacity(double op);
-        void stroke_opacity(double op);
-        void line_join(line_join_e join);
-        void line_cap(line_cap_e cap);
-        void miter_limit(double ml);
-        trans_affine& transform();
-
-        // Make all polygons CCW-oriented
-        void arrange_orientations()
-        {
-            m_storage.arrange_orientations_all_paths(path_flags_ccw);
-        }
-
-        // Expand all polygons 
-        void expand(double value)
-        {
-            m_curved_trans_contour.width(value);
-        }
-
-        unsigned operator [](unsigned idx)
-        {
-            m_transform = m_attr_storage[idx].transform;
-            return m_attr_storage[idx].index;
-        }
-
-        void bounding_rect(double* x1, double* y1, double* x2, double* y2)
-        {
-            agg::conv_transform<agg::path_storage> trans(m_storage, m_transform);
-            agg::bounding_rect(trans, *this, 0, m_attr_storage.size(), x1, y1, x2, y2);
-        }
-
-        // Rendering. One can specify two additional parameters: 
-        // trans_affine and opacity. They can be used to transform the whole
-        // image and/or to make it translucent.
-        template<class Rasterizer, class Scanline, class Renderer> 
-        void render(Rasterizer& ras, 
-                    Scanline& sl,
-                    Renderer& ren, 
-                    const trans_affine& mtx, 
-                    const rect_i& cb,
-                    double opacity=1.0)
-        {
-            unsigned i;
-
-            ras.clip_box(cb.x1, cb.y1, cb.x2, cb.y2);
-            m_curved_count.count(0);
-
-            for(i = 0; i < m_attr_storage.size(); i++)
-            {
-                const path_attributes& attr = m_attr_storage[i];
-                m_transform = attr.transform;
-                m_transform *= mtx;
-                double scl = m_transform.scale();
-                //m_curved.approximation_method(curve_inc);
-                m_curved.approximation_scale(scl);
-                m_curved.angle_tolerance(0.0);
-
-                rgba8 color;
-
-                if(attr.fill_flag)
-                {
-                    ras.reset();
-                    ras.filling_rule(attr.even_odd_flag ? fill_even_odd : fill_non_zero);
-                    if(fabs(m_curved_trans_contour.width()) < 0.0001)
-                    {
-                        ras.add_path(m_curved_trans, attr.index);
-                    }
-                    else
-                    {
-                        m_curved_trans_contour.miter_limit(attr.miter_limit);
-                        ras.add_path(m_curved_trans_contour, attr.index);
-                    }
-
-                    color = attr.fill_color;
-                    color.opacity(color.opacity() * opacity);
-                    ren.color(color);
-                    agg::render_scanlines(ras, sl, ren);
-                }
-
-                if(attr.stroke_flag)
-                {
-                    m_curved_stroked.width(attr.stroke_width);
-                    //m_curved_stroked.line_join((attr.line_join == miter_join) ? miter_join_round : attr.line_join);
-                    m_curved_stroked.line_join(attr.line_join);
-                    m_curved_stroked.line_cap(attr.line_cap);
-                    m_curved_stroked.miter_limit(attr.miter_limit);
-                    m_curved_stroked.inner_join(inner_round);
-                    m_curved_stroked.approximation_scale(scl);
-
-                    // If the *visual* line width is considerable we 
-                    // turn on processing of curve cusps.
-                    //---------------------
-                    if(attr.stroke_width * scl > 1.0)
-                    {
-                        m_curved.angle_tolerance(0.2);
-                    }
-                    ras.reset();
-                    ras.filling_rule(fill_non_zero);
-                    ras.add_path(m_curved_stroked_trans, attr.index);
-                    color = attr.stroke_color;
-                    color.opacity(color.opacity() * opacity);
-                    ren.color(color);
-                    agg::render_scanlines(ras, sl, ren);
-                }
-            }
-        }
-
-    private:
-        path_attributes& cur_attr();
-
-        path_storage   m_storage;
-        attr_storage   m_attr_storage;
-        attr_storage   m_attr_stack;
-        trans_affine   m_transform;
-
-        curved                       m_curved;
-        curved_count                 m_curved_count;
-
-        curved_stroked               m_curved_stroked;
-        curved_stroked_trans         m_curved_stroked_trans;
-
-        curved_trans                 m_curved_trans;
-        curved_trans_contour         m_curved_trans_contour;
-    };
-
-}
-}
-
-#endif
diff --git a/src/agg_svg/agg_svg_path_tokenizer.cpp b/src/agg_svg/agg_svg_path_tokenizer.cpp
deleted file mode 100644
index bd49519bf..000000000
--- a/src/agg_svg/agg_svg_path_tokenizer.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software 
-// is granted provided this copyright notice appears in all copies. 
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// SVG path tokenizer.
-//
-//----------------------------------------------------------------------------
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "agg_svg_exception.h"
-#include "agg_svg_path_tokenizer.h"
-
-
-namespace agg 
-{ 
-namespace svg
-{
-
-    //------------------------------------------------------------------------
-    const char path_tokenizer::s_commands[]   = "+-MmZzLlHhVvCcSsQqTtAaFfPp";
-    const char path_tokenizer::s_numeric[]    = ".Ee0123456789";
-    const char path_tokenizer::s_separators[] = " ,\t\n\r";
-
-    //------------------------------------------------------------------------
-    path_tokenizer::path_tokenizer()
-        : m_path(0), m_last_command(0), m_last_number(0.0)
-    {
-        init_char_mask(m_commands_mask,   s_commands);
-        init_char_mask(m_numeric_mask,    s_numeric);
-        init_char_mask(m_separators_mask, s_separators);
-    }
-
-
-    //------------------------------------------------------------------------
-    void path_tokenizer::set_path_str(const char* str)
-    {
-        m_path = str;
-        m_last_command = 0;
-        m_last_number = 0.0;
-    }
-
-
-    //------------------------------------------------------------------------
-    void path_tokenizer::init_char_mask(char* mask, const char* char_set)
-    {
-        memset(mask, 0, 256/8);
-        while(*char_set) 
-        {
-            unsigned c = unsigned(*char_set++) & 0xFF;
-            mask[c >> 3] |= 1 << (c & 7);
-        }
-    }
-
-
-    //------------------------------------------------------------------------
-    bool path_tokenizer::next()
-    {
-        if(m_path == 0) return false;
-
-        // Skip all white spaces and other garbage
-        while(*m_path && !is_command(*m_path) && !is_numeric(*m_path)) 
-        {
-            if(!is_separator(*m_path))
-            {
-                char buf[100];
-                sprintf(buf, "path_tokenizer::next : Invalid Character %c", *m_path);
-                throw exception(buf);
-            }
-            m_path++;
-        }
-
-        if(*m_path == 0) return false;
-
-        if(is_command(*m_path))
-        {
-            // Check if the command is a numeric sign character
-            if(*m_path == '-' || *m_path == '+')
-            {
-                return parse_number();
-            }
-            m_last_command = *m_path++;
-            while(*m_path && is_separator(*m_path)) m_path++;
-            if(*m_path == 0) return true;
-        }
-        return parse_number();
-    }
-
-
-
-    //------------------------------------------------------------------------
-    double path_tokenizer::next(char cmd)
-    {
-        if(!next()) throw exception("parse_path: Unexpected end of path");
-        if(last_command() != cmd)
-        {
-            char buf[100];
-            sprintf(buf, "parse_path: Command %c: bad or missing parameters", cmd);
-            throw exception(buf);
-        }
-        return last_number();
-    }
-
-
-    //------------------------------------------------------------------------
-    bool path_tokenizer::parse_number()
-    {
-        char buf[256]; // Should be enough for any number
-        char* buf_ptr = buf;
-
-        // Copy all sign characters
-        while(buf_ptr < buf+255 && *m_path == '-' || *m_path == '+')
-        {
-            *buf_ptr++ = *m_path++;
-        }
-
-        // Copy all numeric characters
-		bool dot_seen = false;
-        while(buf_ptr < buf+255 && is_numeric(*m_path))
-        {
-			char c = *m_path;
-			if (c == '.') {
-				if (dot_seen)
-					break;
-				dot_seen = true;
-			}
-            *buf_ptr++ = *m_path++;
-        }
-        *buf_ptr = 0;
-        m_last_number = atof(buf);
-        return true;
-    }
-
-
-} //namespace svg
-} //namespace agg
-
-
-
-
diff --git a/src/agg_svg/agg_svg_path_tokenizer.h b/src/agg_svg/agg_svg_path_tokenizer.h
deleted file mode 100644
index 591ec0e72..000000000
--- a/src/agg_svg/agg_svg_path_tokenizer.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software 
-// is granted provided this copyright notice appears in all copies. 
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// SVG path tokenizer.
-//
-//----------------------------------------------------------------------------
-#ifndef AGG_SVG_PATH_TOKENIZER_INCLUDED
-#define AGG_SVG_PATH_TOKENIZER_INCLUDED
-
-#include "agg_svg_exception.h"
-
-namespace agg 
-{ 
-namespace svg
-{
-    // SVG path tokenizer. 
-    // Example:
-    //
-    // agg::svg::path_tokenizer tok;
-    //
-    // tok.set_str("M-122.304 84.285L-122.304 84.285 122.203 86.179 ");
-    // while(tok.next())
-    // {
-    //     printf("command='%c' number=%f\n", 
-    //             tok.last_command(), 
-    //             tok.last_number());
-    // }
-    //
-    // The tokenizer does all the routine job of parsing the SVG paths.
-    // It doesn't recognize any graphical primitives, it even doesn't know
-    // anything about pairs of coordinates (X,Y). The purpose of this class 
-    // is to tokenize the numeric values and commands. SVG paths can 
-    // have single numeric values for Horizontal or Vertical line_to commands 
-    // as well as more than two coordinates (4 or 6) for Bezier curves 
-    // depending on the semantics of the command.
-    // The behaviour is as follows:
-    //
-    // Each call to next() returns true if there's new command or new numeric
-    // value or false when the path ends. How to interpret the result
-    // depends on the sematics of the command. For example, command "C" 
-    // (cubic Bezier curve) implies 6 floating point numbers preceded by this 
-    // command. If the command assumes no arguments (like z or Z) the 
-    // the last_number() values won't change, that is, last_number() always
-    // returns the last recognized numeric value, so does last_command().
-    //===============================================================
-    class path_tokenizer
-    {
-     public:
-        path_tokenizer();
-
-        void set_path_str(const char* str);
-        bool next();
-
-        double next(char cmd);
-
-        char   last_command() const { return m_last_command; }
-        double last_number() const { return m_last_number; }
-
-
-    private:
-        static void init_char_mask(char* mask, const char* char_set);
-
-        bool contains(const char* mask, unsigned c) const
-        {
-            return (mask[(c >> 3) & (256/8-1)] & (1 << (c & 7))) != 0;
-        }
-
-        bool is_command(unsigned c) const
-        {
-            return contains(m_commands_mask, c);
-        }
-
-        bool is_numeric(unsigned c) const
-        {
-            return contains(m_numeric_mask, c);
-        }
-
-        bool is_separator(unsigned c) const
-        {
-            return contains(m_separators_mask, c);
-        }
-
-        bool parse_number();
-
-        char m_separators_mask[256/8];
-        char m_commands_mask[256/8];
-        char m_numeric_mask[256/8];
-
-        const char* m_path;
-        double m_last_number;
-        char   m_last_command;
-
-        static const char s_commands[];
-        static const char s_numeric[];
-        static const char s_separators[];
-    };
-
-} //namespace svg
-} //namespace agg
-
-
-#endif
diff --git a/src/agg_svg/agg_trans_affine.cpp b/src/agg_svg/agg_trans_affine.cpp
deleted file mode 100644
index 151b1d728..000000000
--- a/src/agg_svg/agg_trans_affine.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#include <agg/agg_trans_affine.h>
-
-
-
-namespace agg
-{
-
-    //------------------------------------------------------------------------
-    const trans_affine& trans_affine::parl_to_parl(const double* src, 
-                                                   const double* dst)
-    {
-        sx  = src[2] - src[0];
-        shy = src[3] - src[1];
-        shx = src[4] - src[0];
-        sy  = src[5] - src[1];
-        tx  = src[0];
-        ty  = src[1];
-        invert();
-        multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1], 
-                              dst[4] - dst[0], dst[5] - dst[1],
-                              dst[0], dst[1]));
-        return *this;
-    }
-
-    //------------------------------------------------------------------------
-    const trans_affine& trans_affine::rect_to_parl(double x1, double y1, 
-                                                   double x2, double y2, 
-                                                   const double* parl)
-    {
-        double src[6];
-        src[0] = x1; src[1] = y1;
-        src[2] = x2; src[3] = y1;
-        src[4] = x2; src[5] = y2;
-        parl_to_parl(src, parl);
-        return *this;
-    }
-
-    //------------------------------------------------------------------------
-    const trans_affine& trans_affine::parl_to_rect(const double* parl, 
-                                                   double x1, double y1, 
-                                                   double x2, double y2)
-    {
-        double dst[6];
-        dst[0] = x1; dst[1] = y1;
-        dst[2] = x2; dst[3] = y1;
-        dst[4] = x2; dst[5] = y2;
-        parl_to_parl(parl, dst);
-        return *this;
-    }
-
-    //------------------------------------------------------------------------
-    const trans_affine& trans_affine::multiply(const trans_affine& m)
-    {
-        double t0 = sx  * m.sx + shy * m.shx;
-        double t2 = shx * m.sx + sy  * m.shx;
-        double t4 = tx  * m.sx + ty  * m.shx + m.tx;
-        shy = sx  * m.shy + shy * m.sy;
-        sy  = shx * m.shy + sy  * m.sy;
-        ty  = tx  * m.shy + ty  * m.sy + m.ty;
-        sx  = t0;
-        shx = t2;
-        tx  = t4;
-        return *this;
-    }
-
-
-    //------------------------------------------------------------------------
-    const trans_affine& trans_affine::invert()
-    {
-        double d  = determinant_reciprocal();
-
-        double t0  =  sy  * d;
-               sy  =  sx  * d;
-               shy = -shy * d;
-               shx = -shx * d;
-
-        double t4 = -tx * t0  - ty * shx;
-               ty = -tx * shy - ty * sy;
-
-        sx = t0;
-        tx = t4;
-        return *this;
-    }
-
-
-   //------------------------------------------------------------------------
-    const trans_affine& trans_affine::flip_x()
-    {
-        sx  = -sx;
-        shy = -shy;
-        tx  = -tx;
-        return *this;
-    }
-
-    //------------------------------------------------------------------------
-    const trans_affine& trans_affine::flip_y()
-    {
-        shx = -shx;
-        sy  = -sy;
-        ty  = -ty;
-        return *this;
-    }
-
-    //------------------------------------------------------------------------
-    const trans_affine& trans_affine::reset()
-    {
-        sx  = sy  = 1.0; 
-        shy = shx = tx = ty = 0.0;
-        return *this;
-    }
-
-    //------------------------------------------------------------------------
-    bool trans_affine::is_identity(double epsilon) const
-    {
-        return is_equal_eps(sx,  1.0, epsilon) &&
-               is_equal_eps(shy, 0.0, epsilon) &&
-               is_equal_eps(shx, 0.0, epsilon) && 
-               is_equal_eps(sy,  1.0, epsilon) &&
-               is_equal_eps(tx,  0.0, epsilon) &&
-               is_equal_eps(ty,  0.0, epsilon);
-    }
-
-    //------------------------------------------------------------------------
-    bool trans_affine::is_valid(double epsilon) const
-    {
-        return fabs(sx) > epsilon && fabs(sy) > epsilon;
-    }
-
-    //------------------------------------------------------------------------
-    bool trans_affine::is_equal(const trans_affine& m, double epsilon) const
-    {
-        return is_equal_eps(sx,  m.sx,  epsilon) &&
-               is_equal_eps(shy, m.shy, epsilon) &&
-               is_equal_eps(shx, m.shx, epsilon) && 
-               is_equal_eps(sy,  m.sy,  epsilon) &&
-               is_equal_eps(tx,  m.tx,  epsilon) &&
-               is_equal_eps(ty,  m.ty,  epsilon);
-    }
-
-    //------------------------------------------------------------------------
-    double trans_affine::rotation() const
-    {
-        double x1 = 0.0;
-        double y1 = 0.0;
-        double x2 = 1.0;
-        double y2 = 0.0;
-        transform(&x1, &y1);
-        transform(&x2, &y2);
-        return atan2(y2-y1, x2-x1);
-    }
-
-    //------------------------------------------------------------------------
-    void trans_affine::translation(double* dx, double* dy) const
-    {
-        *dx = tx;
-        *dy = ty;
-    }
-
-    //------------------------------------------------------------------------
-    void trans_affine::scaling(double* x, double* y) const
-    {
-        double x1 = 0.0;
-        double y1 = 0.0;
-        double x2 = 1.0;
-        double y2 = 1.0;
-        trans_affine t(*this);
-        t *= trans_affine_rotation(-rotation());
-        t.transform(&x1, &y1);
-        t.transform(&x2, &y2);
-        *x = x2 - x1;
-        *y = y2 - y1;
-    }
-
-
-}
-
diff --git a/src/agg_svg/agg_vcgen_contour.cpp b/src/agg_svg/agg_vcgen_contour.cpp
deleted file mode 100644
index ecc087e94..000000000
--- a/src/agg_svg/agg_vcgen_contour.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#include <math.h>
-#include <agg/agg_vcgen_contour.h>
-
-namespace agg
-{
-
-    //------------------------------------------------------------------------
-    vcgen_contour::vcgen_contour() :
-        m_stroker(),
-        m_width(1),
-        m_src_vertices(),
-        m_out_vertices(),
-        m_status(initial),
-        m_src_vertex(0),
-        m_closed(0),
-        m_orientation(0),
-        m_auto_detect(false)
-    {
-    }
-
-    //------------------------------------------------------------------------
-    void vcgen_contour::remove_all()
-    {
-        m_src_vertices.remove_all();
-        m_closed = 0;
-        m_orientation = 0;
-        m_status = initial;
-    }
-
-    //------------------------------------------------------------------------
-    void vcgen_contour::add_vertex(double x, double y, unsigned cmd)
-    {
-        m_status = initial;
-        if(is_move_to(cmd))
-        {
-            m_src_vertices.modify_last(vertex_dist(x, y));
-        }
-        else
-        {
-            if(is_vertex(cmd))
-            {
-                m_src_vertices.add(vertex_dist(x, y));
-            }
-            else
-            {
-                if(is_end_poly(cmd))
-                {
-                    m_closed = get_close_flag(cmd);
-                    if(m_orientation == path_flags_none) 
-                    {
-                        m_orientation = get_orientation(cmd);
-                    }
-                }
-            }
-        }
-    }
-
-    //------------------------------------------------------------------------
-    void vcgen_contour::rewind(unsigned)
-    {
-        if(m_status == initial)
-        {
-            m_src_vertices.close(true);
-            if(m_auto_detect)
-            {
-                if(!is_oriented(m_orientation))
-                {
-                    m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ? 
-                                    path_flags_ccw : 
-                                    path_flags_cw;
-                }
-            }
-            if(is_oriented(m_orientation))
-            {
-                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)
-    {
-        unsigned cmd = path_cmd_line_to;
-        while(!is_stop(cmd))
-        {
-            switch(m_status)
-            {
-            case initial:
-                rewind(0);
-
-            case ready:
-                if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
-                {
-                    cmd = path_cmd_stop;
-                    break;
-                }
-                m_status = outline;
-                cmd = path_cmd_move_to;
-                m_src_vertex = 0;
-                m_out_vertex = 0;
-
-            case outline:
-                if(m_src_vertex >= m_src_vertices.size())
-                {
-                    m_status = end_poly;
-                    break;
-                }
-                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;
-
-            case out_vertices:
-                if(m_out_vertex >= m_out_vertices.size())
-                {
-                    m_status = outline;
-                }
-                else
-                {
-                    const point_d& c = m_out_vertices[m_out_vertex++];
-                    *x = c.x;
-                    *y = c.y;
-                    return cmd;
-                }
-                break;
-
-            case end_poly:
-                if(!m_closed) return path_cmd_stop;
-                m_status = stop;
-                return path_cmd_end_poly | path_flags_close | path_flags_ccw;
-
-            case stop:
-                return path_cmd_stop;
-            }
-        }
-        return cmd;
-    }
-
-}
diff --git a/src/agg_svg/agg_vcgen_stroke.cpp b/src/agg_svg/agg_vcgen_stroke.cpp
deleted file mode 100644
index a8b378195..000000000
--- a/src/agg_svg/agg_vcgen_stroke.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-//          mcseemagg@yahoo.com
-//          http://antigrain.com
-// 
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-// 
-// AGG is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#include <math.h>
-#include <agg/agg_vcgen_stroke.h>
-#include <agg/agg_shorten_path.h>
-
-namespace agg
-{
-
-    //------------------------------------------------------------------------
-    vcgen_stroke::vcgen_stroke() :
-        m_stroker(),
-        m_src_vertices(),
-        m_out_vertices(),
-        m_shorten(0.0),
-        m_closed(0),
-        m_status(initial),
-        m_src_vertex(0),
-        m_out_vertex(0)
-    {
-    }
-
-    //------------------------------------------------------------------------
-    void vcgen_stroke::remove_all()
-    {
-        m_src_vertices.remove_all();
-        m_closed = 0;
-        m_status = initial;
-    }
-
-
-    //------------------------------------------------------------------------
-    void vcgen_stroke::add_vertex(double x, double y, unsigned cmd)
-    {
-        m_status = initial;
-        if(is_move_to(cmd))
-        {
-            m_src_vertices.modify_last(vertex_dist(x, y));
-        }
-        else
-        {
-            if(is_vertex(cmd))
-            {
-                m_src_vertices.add(vertex_dist(x, y));
-            }
-            else
-            {
-                m_closed = get_close_flag(cmd);
-            }
-        }
-    }
-
-    //------------------------------------------------------------------------
-    void vcgen_stroke::rewind(unsigned)
-    {
-        if(m_status == initial)
-        {
-            m_src_vertices.close(m_closed != 0);
-            shorten_path(m_src_vertices, m_shorten, m_closed);
-            if(m_src_vertices.size() < 3) m_closed = 0;
-        }
-        m_status = ready;
-        m_src_vertex = 0;
-        m_out_vertex = 0;
-    }
-
-
-    //------------------------------------------------------------------------
-    unsigned vcgen_stroke::vertex(double* x, double* y)
-    {
-        unsigned cmd = path_cmd_line_to;
-        while(!is_stop(cmd))
-        {
-            switch(m_status)
-            {
-            case initial:
-                rewind(0);
-
-            case ready:
-                if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
-                {
-                    cmd = path_cmd_stop;
-                    break;
-                }
-                m_status = m_closed ? outline1 : cap1;
-                cmd = path_cmd_move_to;
-                m_src_vertex = 0;
-                m_out_vertex = 0;
-                break;
-
-            case cap1:
-                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;
-                m_out_vertex = 0;
-                break;
-
-            case cap2:
-                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;
-                break;
-
-            case outline1:
-                if(m_closed)
-                {
-                    if(m_src_vertex >= m_src_vertices.size())
-                    {
-                        m_prev_status = close_first;
-                        m_status = end_poly1;
-                        break;
-                    }
-                }
-                else
-                {
-                    if(m_src_vertex >= m_src_vertices.size() - 1)
-                    {
-                        m_status = cap2;
-                        break;
-                    }
-                }
-                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;
-                m_out_vertex = 0;
-                break;
-
-            case close_first:
-                m_status = outline2;
-                cmd = path_cmd_move_to;
-
-            case outline2:
-                if(m_src_vertex <= unsigned(m_closed == 0))
-                {
-                    m_status = end_poly2;
-                    m_prev_status = stop;
-                    break;
-                }
-
-                --m_src_vertex;
-                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;
-                m_out_vertex = 0;
-                break;
-
-            case out_vertices:
-                if(m_out_vertex >= m_out_vertices.size())
-                {
-                    m_status = m_prev_status;
-                }
-                else
-                {
-                    const point_d& c = m_out_vertices[m_out_vertex++];
-                    *x = c.x;
-                    *y = c.y;
-                    return cmd;
-                }
-                break;
-
-            case end_poly1:
-                m_status = m_prev_status;
-                return path_cmd_end_poly | path_flags_close | path_flags_ccw;
-
-            case end_poly2:
-                m_status = m_prev_status;
-                return path_cmd_end_poly | path_flags_close | path_flags_cw;
-
-            case stop:
-                cmd = path_cmd_stop;
-                break;
-            }
-        }
-        return cmd;
-    }
-
-}
diff --git a/src/libslic3r/Rasterizer/Rasterizer.cpp b/src/libslic3r/Rasterizer/Rasterizer.cpp
index bd8b54389..5961d9b78 100644
--- a/src/libslic3r/Rasterizer/Rasterizer.cpp
+++ b/src/libslic3r/Rasterizer/Rasterizer.cpp
@@ -27,7 +27,7 @@ public:
     using TPixel = TPixelRenderer::color_type;
     using TRawBuffer = agg::rendering_buffer;
 
-    using TBuffer = std::vector<TPixelRenderer::value_type>;
+    using TBuffer = std::vector<TPixelRenderer::pixel_type>;
 
     using TRendererAA = agg::renderer_scanline_aa_solid<TRawRenderer>;
 
@@ -36,11 +36,6 @@ public:
 
     using Origin = Raster::Origin;
 
-	enum
-	{
-		num_components = 1,
-	};
-
 private:
     Raster::Resolution m_resolution;
     Raster::PixelDim m_pxdim;
@@ -63,7 +58,7 @@ public:
         m_buf(res.pixels()),
         m_rbuf(reinterpret_cast<TPixelRenderer::value_type*>(m_buf.data()),
               res.width_px, res.height_px,
-              int(res.width_px*num_components)),
+              int(res.width_px*TPixelRenderer::num_components)),
         m_pixfmt(m_rbuf),
         m_raw_renderer(m_pixfmt),
         m_renderer(m_raw_renderer),
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index f98819713..9d65a479f 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -121,8 +121,6 @@ set(SLIC3R_GUI_SOURCES
     Utils/Bonjour.hpp
     Utils/PresetUpdater.cpp
     Utils/PresetUpdater.hpp
-    Utils/SVGImport.cpp
-    Utils/SVGImport.hpp
     Utils/Time.cpp
     Utils/Time.hpp
     Utils/HexFile.cpp
@@ -135,10 +133,7 @@ endif ()
 
 add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
 
-target_compile_definitions(libslic3r_gui PUBLIC -DUSE_TBB ${PNG_DEFINITIONS})
-target_include_directories(libslic3r_gui PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${PNG_INCLUDE_DIRS})
-target_link_libraries(libslic3r_gui libslic3r avrdude imgui ${PNG_LIBRARIES} agg_svg)
-
+target_link_libraries(libslic3r_gui libslic3r avrdude imgui)
 if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
     add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE)
 endif ()
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 64d4f040b..91574cda6 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -27,7 +27,6 @@
 
 #include <fstream>
 #include "GUI_App.hpp"
-#include "Utils/SVGImport.hpp"
 
 namespace Slic3r {
 namespace GUI {
@@ -36,9 +35,6 @@ MainFrame::MainFrame() :
 wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, "mainframe"),
         m_printhost_queue_dlg(new PrintHostQueueDialog(this))
 {
-
-    Slic3r::Utils::vojtikuv_pokus();
-
     // Load the icon either from the exe, or from the ico file.
 #if _WIN32
     {
diff --git a/src/slic3r/Utils/SVGImport.cpp b/src/slic3r/Utils/SVGImport.cpp
deleted file mode 100644
index f0639f659..000000000
--- a/src/slic3r/Utils/SVGImport.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "SVGImport.hpp"
-
-#include <agg/agg_basics.h>
-#include <agg/agg_rendering_buffer.h>
-#include <agg/agg_rasterizer_scanline_aa.h>
-#include <agg/agg_scanline_p.h>
-#include <agg/agg_renderer_scanline.h>
-#include <agg/agg_pixfmt_rgba.h>
-#include <agg_svg/agg_svg_parser.h>
-
-#include <png/writer.hpp>
-
-#include <boost/nowide/iostream.hpp>
-
-namespace Slic3r { namespace Utils {
-
-int vojtikuv_pokus()
-{
-	std::string fname = "D:\\temp\\svg_examples\\slicer_vnitrni-menu.svg";
-	try
-    {
-	    agg::svg::path_renderer path;
-        agg::svg::parser prsr(path);
-        prsr.parse(fname.c_str());
-        path.arrange_orientations();
-	    double m_min_x;
-	    double m_min_y;
-	    double m_max_x;
-	    double m_max_y;
-        path.bounding_rect(&m_min_x, &m_min_y, &m_max_x, &m_max_y);
-//        caption(p.title());
-
-
-//        typedef agg::pixfmt_bgra32 pixfmt;
-		typedef agg::pixfmt_rgba32 pixfmt;
-        typedef agg::renderer_base<pixfmt> renderer_base;
-        typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
-
-        unsigned int width_px = 1000;
-        unsigned int height_px = 1000;
-		std::vector<unsigned char> buffer(width_px * height_px * 4, 0);
-		agg::rendering_buffer rbuf(reinterpret_cast<pixfmt::value_type*>(buffer.data()), width_px, height_px, int(width_px * 4));
-        pixfmt pixf(rbuf);
-        renderer_base rb(pixf);
-        renderer_solid ren(rb);
-
-        rb.clear(agg::rgba(1,1,1));
-
-        agg::rasterizer_scanline_aa<> ras;
-        agg::scanline_p8 sl;
-        agg::trans_affine mtx;
-
-        ras.gamma(agg::gamma_power(1.));
-        mtx *= agg::trans_affine_translation(- m_min_x, - m_min_y);
-		mtx *= agg::trans_affine_scaling(double(width_px) / (m_max_x - m_min_x), double(height_px) / (m_max_y - m_min_y));
-        
-        path.expand(1.);
-        path.render(ras, sl, ren, mtx, rb.clip_box(), 1.0);
-
-//        ren.color(agg::rgba(0,0,0));
-        ren.color(agg::rgba(1,1,1));
-		agg::render_scanlines(ras, sl, ren);
-
-
-
-
-
-
-        try {
-			boost::nowide::ofstream c;
-			c.open("d:\\temp\\rasterized.png", std::ios::out | std::ios::binary | std::ios::trunc);
-            png::writer<std::ostream> wr(c);
-            wr.set_bit_depth(8);
-            wr.set_color_type(png::color_type_rgb_alpha);
-            wr.set_width(width_px);
-            wr.set_height(height_px);
-            wr.set_compression_type(png::compression_type_default);
-            wr.write_info();
-            auto ptr = reinterpret_cast<png::byte*>(buffer.data());
-            unsigned stride = 4 * width_px;
-            for(unsigned r = 0; r < height_px; ++ r, ptr += stride)
-                wr.write_row(ptr);
-            wr.write_end_info();
-			c.close();
-		}
-		catch (std::exception &ex) {
-			printf("Hu!");
-		}
-    }
-    catch(agg::svg::exception& e)
-    {
-//        app.message(e.msg());
-    }
-
-	return 0;
-}
-
-} } // namespace Slic3r::Utils
diff --git a/src/slic3r/Utils/SVGImport.hpp b/src/slic3r/Utils/SVGImport.hpp
deleted file mode 100644
index 9dedb2431..000000000
--- a/src/slic3r/Utils/SVGImport.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef slic3r_Utils_SVGImport_hpp_
-#define slic3r_Utils_SVGImport_hpp_
-
-namespace Slic3r {
-namespace Utils {
-
-int vojtikuv_pokus();
-
-}; // namespace Utils
-}; // namespace Slic3r
-
-#endif /* slic3r_Utils_SVGImport_hpp_ */