aboutsummaryrefslogtreecommitdiff
blob: b0be2583fcea38a3bea875b420b440fa4ad57743 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
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