[agg] Add patches.

Jon Ciesla limb at fedoraproject.org
Mon Jun 10 13:13:05 UTC 2013


commit 599c4ed6ec6dac3aba9e3181ca86e40fcf3cd106
Author: Jon Ciesla <limburgher at gmail.com>
Date:   Mon Jun 10 08:08:22 2013 -0500

    Add patches.

 ...on-terminating-loop-conditions-when-len-1.patch |   81 ++++++++
 ...ion-by-aborting-if-the-co-ordinates-are-t.patch |   40 ++++
 ...ates-from-previous-vertex-if-last-command.patch |   30 +++
 ...izer_outline_aa-ignore-close_polygon-when.patch |  138 ++++++++++++++
 0005-Remove-VC-6-workaround.patch                  |   52 ++++++
 ...-Implement-grain-merge-blending-mode-GIMP.patch |   85 +++++++++
 ...mplement-grain-extract-blending-mode-GIMP.patch |   84 +++++++++
 ...tiplication-and-division-operators-as-con.patch |   36 ++++
 0009-Add-a-static-identity-transformation.patch    |   37 ++++
 0010-Add-renderer_scanline_aa_alpha.patch          |  193 ++++++++++++++++++++
 ...Avoid-division-by-zero-in-color-burn-mode.patch |   58 ++++++
 11 files changed, 834 insertions(+), 0 deletions(-)
---
diff --git a/0001-Fix-non-terminating-loop-conditions-when-len-1.patch b/0001-Fix-non-terminating-loop-conditions-when-len-1.patch
new file mode 100644
index 0000000..b5f57e5
--- /dev/null
+++ b/0001-Fix-non-terminating-loop-conditions-when-len-1.patch
@@ -0,0 +1,81 @@
+From 085983cdd2bdf79247a12fcee603e6f1bd6b587e Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 10:55:37 +0100
+Subject: [PATCH 01/11] Fix non-terminating loop conditions when len=1
+
+-   while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
++   while(abs(sx - lp.x1) + abs(sy - lp.y1) > 1 + lp2.len)
+    {
+        sx = (lp.x1 + sx) >> 1;
+        sy = (lp.y1 + sy) >> 1;
+    }
+---
+ include/agg_renderer_outline_aa.h    | 8 ++++----
+ include/agg_renderer_outline_image.h | 4 ++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/include/agg_renderer_outline_aa.h b/include/agg_renderer_outline_aa.h
+index ce25a2e..cb2aa00 100644
+--- a/include/agg_renderer_outline_aa.h
++++ b/include/agg_renderer_outline_aa.h
+@@ -1659,7 +1659,7 @@ namespace agg
+                         }
+                         else
+                         {
+-                            while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
++                            while(abs(sx - lp.x1) + abs(sy - lp.y1) > 1 + lp2.len)
+                             {
+                                 sx = (lp.x1 + sx) >> 1;
+                                 sy = (lp.y1 + sy) >> 1;
+@@ -1726,7 +1726,7 @@ namespace agg
+                         }
+                         else
+                         {
+-                            while(abs(ex - lp.x2) + abs(ey - lp.y2) > lp2.len)
++                            while(abs(ex - lp.x2) + abs(ey - lp.y2) > 1 + lp2.len)
+                             {
+                                 ex = (lp.x2 + ex) >> 1;
+                                 ey = (lp.y2 + ey) >> 1;
+@@ -1798,7 +1798,7 @@ namespace agg
+                         }
+                         else
+                         {
+-                            while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
++                            while(abs(sx - lp.x1) + abs(sy - lp.y1) > 1 + lp2.len)
+                             {
+                                 sx = (lp.x1 + sx) >> 1;
+                                 sy = (lp.y1 + sy) >> 1;
+@@ -1811,7 +1811,7 @@ namespace agg
+                         }
+                         else
+                         {
+-                            while(abs(ex - lp.x2) + abs(ey - lp.y2) > lp2.len)
++                            while(abs(ex - lp.x2) + abs(ey - lp.y2) > 1 + lp2.len)
+                             {
+                                 ex = (lp.x2 + ex) >> 1;
+                                 ey = (lp.y2 + ey) >> 1;
+diff --git a/include/agg_renderer_outline_image.h b/include/agg_renderer_outline_image.h
+index fbfac10..66d2b9a 100644
+--- a/include/agg_renderer_outline_image.h
++++ b/include/agg_renderer_outline_image.h
+@@ -969,7 +969,7 @@ namespace agg
+                         }
+                         else
+                         {
+-                            while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
++                            while(abs(sx - lp.x1) + abs(sy - lp.y1) > 1 + lp2.len)
+                             {
+                                 sx = (lp.x1 + sx) >> 1;
+                                 sy = (lp.y1 + sy) >> 1;
+@@ -982,7 +982,7 @@ namespace agg
+                         }
+                         else
+                         {
+-                            while(abs(ex - lp.x2) + abs(ey - lp.y2) > lp2.len)
++                            while(abs(ex - lp.x2) + abs(ey - lp.y2) > 1 + lp2.len)
+                             {
+                                 ex = (lp.x2 + ex) >> 1;
+                                 ey = (lp.y2 + ey) >> 1;
+-- 
+1.8.1.4
+
diff --git a/0002-Cure-recursion-by-aborting-if-the-co-ordinates-are-t.patch b/0002-Cure-recursion-by-aborting-if-the-co-ordinates-are-t.patch
new file mode 100644
index 0000000..18d43dd
--- /dev/null
+++ b/0002-Cure-recursion-by-aborting-if-the-co-ordinates-are-t.patch
@@ -0,0 +1,40 @@
+From dab3a675d4fe1294f12f65c7ae72fd740b043a19 Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 11:03:26 +0100
+Subject: [PATCH 02/11] Cure recursion by aborting if the co-ordinates are to
+ big to handle
+
+---
+ include/agg_rasterizer_cells_aa.h | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/include/agg_rasterizer_cells_aa.h b/include/agg_rasterizer_cells_aa.h
+index d3bb138..3a616d9 100644
+--- a/include/agg_rasterizer_cells_aa.h
++++ b/include/agg_rasterizer_cells_aa.h
+@@ -40,7 +40,8 @@
+ #define AGG_RASTERIZER_CELLS_AA_INCLUDED
+ 
+ #include <string.h>
+-#include <math.h>
++#include <cstdlib>
++#include <limits>
+ #include "agg_math.h"
+ #include "agg_array.h"
+ 
+@@ -333,6 +334,12 @@ namespace agg
+         {
+             int cx = (x1 + x2) >> 1;
+             int cy = (y1 + y2) >> 1;
++
++            // Bail if values are so large they are likely to wrap
++            if ((std::abs(x1) >= std::numeric_limits<int>::max()/2) || (std::abs(y1) >= std::numeric_limits<int>::max()/2) ||
++                (std::abs(x2) >= std::numeric_limits<int>::max()/2) || (std::abs(y2) >= std::numeric_limits<int>::max()/2))
++                    return;
++
+             line(x1, y1, cx, cy);
+             line(cx, cy, x2, y2);
+         }
+-- 
+1.8.1.4
+
diff --git a/0003-Get-coordinates-from-previous-vertex-if-last-command.patch b/0003-Get-coordinates-from-previous-vertex-if-last-command.patch
new file mode 100644
index 0000000..e4cbdba
--- /dev/null
+++ b/0003-Get-coordinates-from-previous-vertex-if-last-command.patch
@@ -0,0 +1,30 @@
+From 3dbfb18b984dd2bdd2b1fd33108817ffe581c09b Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 11:40:49 +0100
+Subject: [PATCH 03/11] Get coordinates from previous vertex if last command is
+ path_cmd_end_poly
+
+---
+ include/agg_path_storage.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/include/agg_path_storage.h b/include/agg_path_storage.h
+index 7be7393..8922fc8 100644
+--- a/include/agg_path_storage.h
++++ b/include/agg_path_storage.h
+@@ -878,6 +878,12 @@ namespace agg
+                 *x += x2;
+                 *y += y2;
+             }
++            else if (!is_stop(m_vertices.last_command()) &&
++                     is_vertex(m_vertices.prev_vertex(&x2, &y2)))
++            {
++                *x += x2;
++                *y += y2;
++            }
+         }
+     }
+ 
+-- 
+1.8.1.4
+
diff --git a/0004-Make-rasterizer_outline_aa-ignore-close_polygon-when.patch b/0004-Make-rasterizer_outline_aa-ignore-close_polygon-when.patch
new file mode 100644
index 0000000..77a5564
--- /dev/null
+++ b/0004-Make-rasterizer_outline_aa-ignore-close_polygon-when.patch
@@ -0,0 +1,138 @@
+From e12c9df003505093b6fc81ed6458185271825146 Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 14:17:43 +0100
+Subject: [PATCH 04/11] Make rasterizer_outline_aa ignore close_polygon when
+ vertex count < 3
+
+---
+ include/agg_rasterizer_outline_aa.h | 107 ++++++++++++++++++------------------
+ 1 file changed, 52 insertions(+), 55 deletions(-)
+
+diff --git a/include/agg_rasterizer_outline_aa.h b/include/agg_rasterizer_outline_aa.h
+index 4d6dd57..24301d5 100644
+--- a/include/agg_rasterizer_outline_aa.h
++++ b/include/agg_rasterizer_outline_aa.h
+@@ -333,68 +333,65 @@ namespace agg
+         int y2;
+         int lprev;
+ 
+-        if(close_polygon)
++        if(close_polygon && (m_src_vertices.size() >= 3))
+         {
+-            if(m_src_vertices.size() >= 3)
++            dv.idx = 2;
++
++            v     = &m_src_vertices[m_src_vertices.size() - 1];
++            x1    = v->x;
++            y1    = v->y;
++            lprev = v->len;
++
++            v  = &m_src_vertices[0];
++            x2 = v->x;
++            y2 = v->y;
++            dv.lcurr = v->len;
++            line_parameters prev(x1, y1, x2, y2, lprev);
++
++            v = &m_src_vertices[1];
++            dv.x1    = v->x;
++            dv.y1    = v->y;
++            dv.lnext = v->len;
++            dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
++
++            v = &m_src_vertices[dv.idx];
++            dv.x2 = v->x;
++            dv.y2 = v->y;
++            dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
++
++            dv.xb1 = 0;
++            dv.yb1 = 0;
++            dv.xb2 = 0;
++            dv.yb2 = 0;
++
++            switch(m_line_join)
+             {
+-                dv.idx = 2;
+-
+-                v     = &m_src_vertices[m_src_vertices.size() - 1];
+-                x1    = v->x;
+-                y1    = v->y;
+-                lprev = v->len;
+-
+-                v  = &m_src_vertices[0];
+-                x2 = v->x;
+-                y2 = v->y;
+-                dv.lcurr = v->len;
+-                line_parameters prev(x1, y1, x2, y2, lprev);
+-
+-                v = &m_src_vertices[1];
+-                dv.x1    = v->x;
+-                dv.y1    = v->y;
+-                dv.lnext = v->len;
+-                dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
+-
+-                v = &m_src_vertices[dv.idx];
+-                dv.x2 = v->x;
+-                dv.y2 = v->y;
+-                dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
+-
+-                dv.xb1 = 0;
+-                dv.yb1 = 0;
+-                dv.xb2 = 0;
+-                dv.yb2 = 0;
+-
+-                switch(m_line_join)
+-                {
+-                case outline_no_join:
+-                    dv.flags = 3;
+-                    break;
++            case outline_no_join:
++                dv.flags = 3;
++                break;
+ 
+-                case outline_miter_join:
+-                case outline_round_join:
+-                    dv.flags = 
+-                            (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
+-                        ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
+-                    break;
++            case outline_miter_join:
++            case outline_round_join:
++                dv.flags = 
++                        (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
++                    ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
++                break;
+ 
+-                case outline_miter_accurate_join:
+-                    dv.flags = 0;
+-                    break;
+-                }
++            case outline_miter_accurate_join:
++                dv.flags = 0;
++                break;
++            }
+ 
+-                if((dv.flags & 1) == 0 && m_line_join != outline_round_join)
+-                {
+-                    bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
+-                }
++            if((dv.flags & 1) == 0 && m_line_join != outline_round_join)
++            {
++                bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
++            }
+ 
+-                if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
+-                {
+-                    bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
+-                }
+-                draw(dv, 0, m_src_vertices.size());
++            if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
++            {
++                bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
+             }
++            draw(dv, 0, m_src_vertices.size());
+         }
+         else
+         {
+-- 
+1.8.1.4
+
diff --git a/0005-Remove-VC-6-workaround.patch b/0005-Remove-VC-6-workaround.patch
new file mode 100644
index 0000000..78d8ec7
--- /dev/null
+++ b/0005-Remove-VC-6-workaround.patch
@@ -0,0 +1,52 @@
+From 9fb6c7e39bb0cf01f7268a55b13d7ae828ab8321 Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 15:04:05 +0100
+Subject: [PATCH 05/11] Remove VC++ 6 workaround
+
+---
+ include/agg_renderer_scanline.h | 29 +----------------------------
+ 1 file changed, 1 insertion(+), 28 deletions(-)
+
+diff --git a/include/agg_renderer_scanline.h b/include/agg_renderer_scanline.h
+index c3bb6f0..c27ca60 100644
+--- a/include/agg_renderer_scanline.h
++++ b/include/agg_renderer_scanline.h
+@@ -79,34 +79,7 @@ namespace agg
+             sl.reset(ras.min_x(), ras.max_x());
+             while(ras.sweep_scanline(sl))
+             {
+-                //render_scanline_aa_solid(sl, ren, ren_color);
+-
+-                // This code is equivalent to the above call (copy/paste). 
+-                // It's just a "manual" optimization for old compilers,
+-                // like Microsoft Visual C++ v6.0
+-                //-------------------------------
+-                int y = sl.y();
+-                unsigned num_spans = sl.num_spans();
+-                typename Scanline::const_iterator span = sl.begin();
+-
+-                for(;;)
+-                {
+-                    int x = span->x;
+-                    if(span->len > 0)
+-                    {
+-                        ren.blend_solid_hspan(x, y, (unsigned)span->len, 
+-                                              ren_color, 
+-                                              span->covers);
+-                    }
+-                    else
+-                    {
+-                        ren.blend_hline(x, y, (unsigned)(x - span->len - 1), 
+-                                        ren_color, 
+-                                        *(span->covers));
+-                    }
+-                    if(--num_spans == 0) break;
+-                    ++span;
+-                }
++                render_scanline_aa_solid(sl, ren, ren_color);
+             }
+         }
+     }
+-- 
+1.8.1.4
+
diff --git a/0006-Implement-grain-merge-blending-mode-GIMP.patch b/0006-Implement-grain-merge-blending-mode-GIMP.patch
new file mode 100644
index 0000000..2526d06
--- /dev/null
+++ b/0006-Implement-grain-merge-blending-mode-GIMP.patch
@@ -0,0 +1,85 @@
+From 09c4b068b9512e33736e6f23896ad2522f3b65da Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 15:31:01 +0100
+Subject: [PATCH 06/11] Implement grain-merge blending mode (GIMP)
+
+---
+ include/agg_pixfmt_rgba.h | 42 ++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 40 insertions(+), 2 deletions(-)
+
+diff --git a/include/agg_pixfmt_rgba.h b/include/agg_pixfmt_rgba.h
+index 79d10dc..99b1c9f 100644
+--- a/include/agg_pixfmt_rgba.h
++++ b/include/agg_pixfmt_rgba.h
+@@ -1401,9 +1401,46 @@ namespace agg
+         }
+     };
+ 
++    //================================================comp_op_rgba_grain_merge
++    template <typename ColorT, typename Order> struct comp_op_rgba_grain_merge
++    {
++        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
++        };
+ 
++        // E = I + M - 128
++        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 = sr + p[Order::R] - 128;
++                calc_type dg = sg + p[Order::G] - 128;
++                calc_type db = sb + p[Order::B] - 128;
++                p[Order::R] = (value_type)(dr < 0 ? 0 : (dr > 255 ? 255 : dr));
++                p[Order::G] = (value_type)(dg < 0 ? 0 : (dg > 255 ? 255 : dg));
++                p[Order::B] = (value_type)(db < 0 ? 0 : (db > 255 ? 255 : db));
++                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
+@@ -1451,6 +1488,7 @@ namespace agg
+         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,
++        comp_op_rgba_grain_merge<ColorT,Order>::blend_pix,
+         0
+     };
+ 
+@@ -1486,6 +1524,7 @@ namespace agg
+         comp_op_contrast,      //----comp_op_contrast
+         comp_op_invert,        //----comp_op_invert
+         comp_op_invert_rgb,    //----comp_op_invert_rgb
++        comp_op_grain_merge,   //----comp_op_grain_merge
+ 
+         end_of_comp_op_e
+     };
+@@ -2908,4 +2947,3 @@ namespace agg
+ }
+ 
+ #endif
+-
+-- 
+1.8.1.4
+
diff --git a/0007-Implement-grain-extract-blending-mode-GIMP.patch b/0007-Implement-grain-extract-blending-mode-GIMP.patch
new file mode 100644
index 0000000..656f885
--- /dev/null
+++ b/0007-Implement-grain-extract-blending-mode-GIMP.patch
@@ -0,0 +1,84 @@
+From 6cef3ddecc1b8a614ba4d47bf9daf6b04bea9995 Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 15:43:18 +0100
+Subject: [PATCH 07/11] Implement grain-extract blending mode (GIMP)
+
+---
+ include/agg_pixfmt_rgba.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+diff --git a/include/agg_pixfmt_rgba.h b/include/agg_pixfmt_rgba.h
+index 99b1c9f..e0a6dc1 100644
+--- a/include/agg_pixfmt_rgba.h
++++ b/include/agg_pixfmt_rgba.h
+@@ -1442,6 +1442,51 @@ namespace agg
+         }
+     };
+ 
++    //==============================================comp_op_rgba_grain_extract
++    template <typename ColorT, typename Order> struct comp_op_rgba_grain_extract
++    {
++        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
++        };
++
++        // E = I - M + 128
++        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] * sa + 255) >> 8;
++            calc_type dr = p[Order::R] - sr + 128;
++            calc_type dg = p[Order::G] - sg + 128;
++            calc_type db = p[Order::B] - sb + 128;
++
++            dr = dr < 0 ? 0 : (dr > 255 ? 255 : dr);
++            dg = dg < 0 ? 0 : (dg > 255 ? 255 : dg);
++            db = db < 0 ? 0 : (db > 255 ? 255 : db);
++
++            p[Order::A] = da;
++
++            if(da < 255)
++            {
++                p[Order::R] = (dr * da + 255) >> 8;
++                p[Order::G] = (dg * da + 255) >> 8;
++                p[Order::B] = (db * da + 255) >> 8;
++            }
++            else
++            {
++                p[Order::R] = dr;
++                p[Order::G] = dg;
++                p[Order::B] = db;
++            }
++        }
++    };
++
+     //======================================================comp_op_table_rgba
+     template<class ColorT, class Order> struct comp_op_table_rgba
+     {
+@@ -1489,6 +1534,7 @@ namespace agg
+         comp_op_rgba_invert     <ColorT,Order>::blend_pix,
+         comp_op_rgba_invert_rgb <ColorT,Order>::blend_pix,
+         comp_op_rgba_grain_merge<ColorT,Order>::blend_pix,
++        comp_op_rgba_grain_extract<ColorT,Order>::blend_pix,
+         0
+     };
+ 
+@@ -1525,6 +1571,7 @@ namespace agg
+         comp_op_invert,        //----comp_op_invert
+         comp_op_invert_rgb,    //----comp_op_invert_rgb
+         comp_op_grain_merge,   //----comp_op_grain_merge
++        comp_op_grain_extract, //----comp_op_grain_extract
+ 
+         end_of_comp_op_e
+     };
+-- 
+1.8.1.4
+
diff --git a/0008-Declare-multiplication-and-division-operators-as-con.patch b/0008-Declare-multiplication-and-division-operators-as-con.patch
new file mode 100644
index 0000000..58fc18a
--- /dev/null
+++ b/0008-Declare-multiplication-and-division-operators-as-con.patch
@@ -0,0 +1,36 @@
+From 6f8f30a6af5b335c14065e421d953b821fb7660f Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 16:15:01 +0100
+Subject: [PATCH 08/11] Declare multiplication and division operators as const
+
+---
+ include/agg_trans_affine.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/agg_trans_affine.h b/include/agg_trans_affine.h
+index a662099..2f602a0 100644
+--- a/include/agg_trans_affine.h
++++ b/include/agg_trans_affine.h
+@@ -216,15 +216,15 @@ namespace agg
+         }
+ 
+         // Multiply the matrix by another one and return
+-        // the result in a separete matrix.
+-        trans_affine operator * (const trans_affine& m)
++        // the result in a separate matrix.
++        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)
++        // and return the result in a separate matrix.
++        trans_affine operator / (const trans_affine& m) const
+         {
+             return trans_affine(*this).multiply_inv(m);
+         }
+-- 
+1.8.1.4
+
diff --git a/0009-Add-a-static-identity-transformation.patch b/0009-Add-a-static-identity-transformation.patch
new file mode 100644
index 0000000..9ee9b79
--- /dev/null
+++ b/0009-Add-a-static-identity-transformation.patch
@@ -0,0 +1,37 @@
+From 7669098f8e80929eec2e380967e12b31b68a4310 Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 16:15:36 +0100
+Subject: [PATCH 09/11] Add a static identity transformation
+
+---
+ include/agg_trans_affine.h | 1 +
+ src/agg_trans_affine.cpp   | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/include/agg_trans_affine.h b/include/agg_trans_affine.h
+index 2f602a0..67fe5ca 100644
+--- a/include/agg_trans_affine.h
++++ b/include/agg_trans_affine.h
+@@ -92,6 +92,7 @@ namespace agg
+     //----------------------------------------------------------------------
+     struct trans_affine
+     {
++        static const trans_affine identity;
+         double sx, shy, shx, sy, tx, ty;
+ 
+         //------------------------------------------ Construction
+diff --git a/src/agg_trans_affine.cpp b/src/agg_trans_affine.cpp
+index aca18c2..b3d9bc0 100644
+--- a/src/agg_trans_affine.cpp
++++ b/src/agg_trans_affine.cpp
+@@ -28,6 +28,7 @@
+ 
+ namespace agg
+ {
++    const trans_affine trans_affine::identity;
+ 
+     //------------------------------------------------------------------------
+     const trans_affine& trans_affine::parl_to_parl(const double* src, 
+-- 
+1.8.1.4
+
diff --git a/0010-Add-renderer_scanline_aa_alpha.patch b/0010-Add-renderer_scanline_aa_alpha.patch
new file mode 100644
index 0000000..33acf70
--- /dev/null
+++ b/0010-Add-renderer_scanline_aa_alpha.patch
@@ -0,0 +1,193 @@
+From 15fa2c5afe649b4f41aede636243c9bea7aa74a4 Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 16:43:25 +0100
+Subject: [PATCH 10/11] Add renderer_scanline_aa_alpha
+
+---
+ include/agg_pixfmt_rgba.h       | 24 +++++++++++++-
+ include/agg_renderer_base.h     | 28 ++++++++++++++++
+ include/agg_renderer_scanline.h | 71 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 122 insertions(+), 1 deletion(-)
+
+diff --git a/include/agg_pixfmt_rgba.h b/include/agg_pixfmt_rgba.h
+index e0a6dc1..d912ba3 100644
+--- a/include/agg_pixfmt_rgba.h
++++ b/include/agg_pixfmt_rgba.h
+@@ -2246,7 +2246,6 @@ namespace agg
+         }
+ 
+ 
+-
+         //--------------------------------------------------------------------
+         void blend_color_vspan(int x, int y,
+                                unsigned len, 
+@@ -2750,6 +2749,29 @@ namespace agg
+         }
+ 
+         //--------------------------------------------------------------------
++        void blend_color_hspan_alpha(int x, int y, unsigned len,
++                                     const color_type* colors,
++                                     value_type alpha,
++                                     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 * alpha + 255) >> 8,
++                                        (colors->g * alpha + 255) >> 8,
++                                        (colors->b * alpha + 255) >> 8,
++                                        (colors->a * alpha + 255) >> 8,
++                                        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,
+diff --git a/include/agg_renderer_base.h b/include/agg_renderer_base.h
+index 1808944..25f07c3 100644
+--- a/include/agg_renderer_base.h
++++ b/include/agg_renderer_base.h
+@@ -37,6 +37,7 @@ namespace agg
+     public:
+         typedef PixelFormat pixfmt_type;
+         typedef typename pixfmt_type::color_type color_type;
++        typedef typename pixfmt_type::color_type::value_type value_type;
+         typedef typename pixfmt_type::row_data row_data;
+ 
+         //--------------------------------------------------------------------
+@@ -383,6 +384,33 @@ namespace agg
+         }
+ 
+         //--------------------------------------------------------------------
++        void blend_color_hspan_alpha(int x, int y, int len,
++                               const color_type* colors,
++                               value_type alpha,
++                               const cover_type* covers,
++                               cover_type cover = agg::cover_full)
++        {
++            if(y > ymax()) return;
++            if(y < ymin()) return;
++
++            if(x < xmin())
++            {
++                int d = xmin() - x;
++                len -= d;
++                if(len <= 0) return;
++                if(covers) covers += d;
++                colors += d;
++                x = xmin();
++            }
++            if(x + len > xmax())
++            {
++                len = xmax() - x + 1;
++                if(len <= 0) return;
++            }
++            m_ren->blend_color_hspan_alpha(x, y, len, colors, alpha,  covers, cover);
++        }
++
++        //--------------------------------------------------------------------
+         void blend_color_vspan(int x, int y, int len, 
+                                const color_type* colors, 
+                                const cover_type* covers,
+diff --git a/include/agg_renderer_scanline.h b/include/agg_renderer_scanline.h
+index c27ca60..4fcb557 100644
+--- a/include/agg_renderer_scanline.h
++++ b/include/agg_renderer_scanline.h
+@@ -156,6 +156,35 @@ namespace agg
+         }
+     }
+ 
++    //================================================render_scanline_aa_alpha
++    template<class Scanline, class BaseRenderer,
++             class SpanAllocator, class SpanGenerator>
++    void render_scanline_aa_alpha(const Scanline& sl, BaseRenderer& ren,
++                                  SpanAllocator& alloc, SpanGenerator& span_gen,
++                                  unsigned alpha)
++    {
++        int y = sl.y();
++
++        unsigned num_spans = sl.num_spans();
++        typename Scanline::const_iterator span = sl.begin();
++        for(;;)
++        {
++            int x = span->x;
++            int len = span->len;
++            const typename Scanline::cover_type* covers = span->covers;
++
++            if(len < 0) len = -len;
++            typename BaseRenderer::color_type* colors = alloc.allocate(len);
++            span_gen.generate(colors, x, y, len);
++            ren.blend_color_hspan_alpha(x, y, len, colors, alpha,
++                                  (span->len < 0) ? 0 : covers, *covers);
++
++            if(--num_spans == 0) break;
++            ++span;
++        }
++    }
++
++
+     //=====================================================render_scanlines_aa
+     template<class Rasterizer, class Scanline, class BaseRenderer, 
+              class SpanAllocator, class SpanGenerator>
+@@ -216,8 +245,50 @@ namespace agg
+     };
+ 
+ 
++    //==============================================renderer_scanline_aa_alpha
++    template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
++    class renderer_scanline_aa_alpha
++    {
++    public:
++        typedef BaseRenderer  base_ren_type;
++        typedef SpanAllocator alloc_type;
++        typedef SpanGenerator span_gen_type;
+ 
++        //--------------------------------------------------------------------
++        renderer_scanline_aa_alpha() : m_ren(0), m_alloc(0), m_span_gen(0), m_alpha(1.0) {}
++        renderer_scanline_aa_alpha(base_ren_type& ren,
++                             alloc_type& alloc,
++                             span_gen_type& span_gen,
++                             unsigned alpha) :
++            m_ren(&ren),
++            m_alloc(&alloc),
++            m_span_gen(&span_gen),
++            m_alpha(alpha)
++        {}
++        void attach(base_ren_type& ren,
++                    alloc_type& alloc,
++                    span_gen_type& span_gen)
++        {
++            m_ren = &ren;
++            m_alloc = &alloc;
++            m_span_gen = &span_gen;
++        }
+ 
++        //--------------------------------------------------------------------
++        void prepare() { m_span_gen->prepare(); }
++
++        //--------------------------------------------------------------------
++        template<class Scanline> void render(const Scanline& sl)
++        {
++            render_scanline_aa_alpha(sl, *m_ren, *m_alloc, *m_span_gen, m_alpha);
++        }
++
++    private:
++        base_ren_type* m_ren;
++        alloc_type*    m_alloc;
++        span_gen_type* m_span_gen;
++        unsigned       m_alpha;
++    };
+ 
+ 
+     //===============================================render_scanline_bin_solid
+-- 
+1.8.1.4
+
diff --git a/0011-Avoid-division-by-zero-in-color-burn-mode.patch b/0011-Avoid-division-by-zero-in-color-burn-mode.patch
new file mode 100644
index 0000000..9b431fe
--- /dev/null
+++ b/0011-Avoid-division-by-zero-in-color-burn-mode.patch
@@ -0,0 +1,58 @@
+From 85de27e76d433db8c577e9475e29794cad5f999a Mon Sep 17 00:00:00 2001
+From: Tom Hughes <tom at compton.nu>
+Date: Sun, 19 May 2013 16:49:08 +0100
+Subject: [PATCH 11/11] Avoid division by zero in color-burn mode
+
+FIXME: re-work using latest math from http://www.w3.org/TR/SVGCompositing/
+---
+ include/agg_pixfmt_rgba.h | 21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/include/agg_pixfmt_rgba.h b/include/agg_pixfmt_rgba.h
+index d912ba3..e30860c 100644
+--- a/include/agg_pixfmt_rgba.h
++++ b/include/agg_pixfmt_rgba.h
+@@ -1027,6 +1027,21 @@ namespace agg
+         //   Dca' = Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa)
+         // 
+         // Da'  = Sa + Da - Sa.Da 
++
++
++        // http://www.w3.org/TR/SVGCompositing/
++        // if Sca == 0 and Dca == Da
++        //   Dca' = Sa × Da + Sca × (1 - Da) + Dca × (1 - Sa)
++        //        = Sa × Da + Dca × (1 - Sa)
++        //        = Da = Dca
++        // otherwise if Sca == 0
++        //   Dca' = Sca × (1 - Da) + Dca × (1 - Sa)
++        //        = Dca × (1 - Sa)
++        // otherwise if Sca > 0
++        //   Dca' = Sa × Da - Sa × Da × min(1, (1 - Dca/Da) × Sa/Sca) + Sca × (1 - Da) + Dca × (1 - Sa)
++        //        = Sa × Da × (1 - min(1, (1 - Dca/Da) × Sa/Sca)) + Sca × (1 - Da) + Dca × (1 - Sa)
++
++        //   sa * da * (255 - std::min(255, (255 - p[0]/da)*(sa/(sc*sa)) +
+         static AGG_INLINE void blend_pix(value_type* p, 
+                                          unsigned sr, unsigned sg, unsigned sb, 
+                                          unsigned sa, unsigned cover)
+@@ -1056,15 +1071,15 @@ namespace agg
+ 
+                 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);
++                   (sr > 0 ? sa * (srda + drsa - sada) / sr + sr * d1a + dr * s1a + base_mask : 0)) >> 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);
++                   (sg > 0 ? sa * (sgda + dgsa - sada) / sg + sg * d1a + dg * s1a + base_mask : 0)) >> 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);
++                   (sb > 0 ? sa * (sbda + dbsa - sada) / sb + sb * d1a + db * s1a + base_mask : 0)) >> base_shift);
+ 
+                 p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+             }
+-- 
+1.8.1.4
+


More information about the scm-commits mailing list