Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7766ebe

Browse files
committed
Workaround for blending bug in new Agg.
1 parent 2a17839 commit 7766ebe

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

src/_backend_agg.h

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,49 @@
3838
#include "path_converters.h"
3939
#include "array.h"
4040

41-
typedef agg::pixfmt_rgba32_plain pixfmt;
41+
/**********************************************************************
42+
WORKAROUND: This class is to workaround a bug in Agg SVN where the
43+
blending of RGBA32 pixels does not preserve enough precision
44+
*/
45+
46+
template<class ColorT, class Order>
47+
struct fixed_blender_rgba_plain : agg::conv_rgba_plain<ColorT, Order>
48+
{
49+
typedef ColorT color_type;
50+
typedef Order order_type;
51+
typedef typename color_type::value_type value_type;
52+
typedef typename color_type::calc_type calc_type;
53+
typedef typename color_type::long_type long_type;
54+
enum base_scale_e { base_shift = color_type::base_shift };
55+
56+
//--------------------------------------------------------------------
57+
static AGG_INLINE void blend_pix(value_type* p,
58+
value_type cr, value_type cg, value_type cb, value_type alpha, agg::cover_type cover)
59+
{
60+
blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
61+
}
62+
63+
//--------------------------------------------------------------------
64+
static AGG_INLINE void blend_pix(value_type* p,
65+
value_type cr, value_type cg, value_type cb, value_type alpha)
66+
{
67+
if(alpha == 0) return;
68+
calc_type a = p[Order::A];
69+
calc_type r = p[Order::R] * a;
70+
calc_type g = p[Order::G] * a;
71+
calc_type b = p[Order::B] * a;
72+
a = ((alpha + a) << base_shift) - alpha * a;
73+
p[Order::A] = (value_type)(a >> base_shift);
74+
p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a);
75+
p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a);
76+
p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a);
77+
}
78+
};
79+
80+
/**********************************************************************/
81+
82+
typedef fixed_blender_rgba_plain<agg::rgba8, agg::order_rgba> fixed_blender_rgba32_plain;
83+
typedef agg::pixfmt_alpha_blend_rgba<fixed_blender_rgba32_plain, agg::rendering_buffer> pixfmt;
4284
typedef agg::renderer_base<pixfmt> renderer_base;
4385
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
4486
typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin;
@@ -831,7 +873,7 @@ inline void RendererAgg::draw_image(GCAgg &gc,
831873
inv_mtx.invert();
832874

833875
typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
834-
typedef agg::image_accessor_clip<agg::pixfmt_rgba32_plain> image_accessor_type;
876+
typedef agg::image_accessor_clip<pixfmt> image_accessor_type;
835877
typedef agg::span_interpolator_linear<> interpolator_type;
836878
typedef agg::span_image_filter_rgba_nn<image_accessor_type, interpolator_type>
837879
image_span_gen_type;

0 commit comments

Comments
 (0)