From 749c8cd11e9e6f81e93ae5ce19258431722b6bdf Mon Sep 17 00:00:00 2001
From: Tom Hughes <tom@compton.nu>
Date: Sun, 19 May 2013 16:43:25 +0100
Subject: [PATCH 10/15] 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 42f0a05..6c4bc37 100644
--- a/include/agg_pixfmt_rgba.h
+++ b/include/agg_pixfmt_rgba.h
@@ -2247,7 +2247,6 @@ namespace agg
         }
 
 
-
         //--------------------------------------------------------------------
         void blend_color_vspan(int x, int y,
                                unsigned len, 
@@ -2751,6 +2750,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

