From 749c8cd11e9e6f81e93ae5ce19258431722b6bdf Mon Sep 17 00:00:00 2001 From: Tom Hughes 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 + 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 @@ -216,8 +245,50 @@ namespace agg }; + //==============================================renderer_scanline_aa_alpha + template + 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 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