|
38 | 38 | #include "path_converters.h"
|
39 | 39 | #include "array.h"
|
40 | 40 |
|
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; |
42 | 84 | typedef agg::renderer_base<pixfmt> renderer_base;
|
43 | 85 | typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
|
44 | 86 | typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin;
|
@@ -831,7 +873,7 @@ inline void RendererAgg::draw_image(GCAgg &gc,
|
831 | 873 | inv_mtx.invert();
|
832 | 874 |
|
833 | 875 | 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; |
835 | 877 | typedef agg::span_interpolator_linear<> interpolator_type;
|
836 | 878 | typedef agg::span_image_filter_rgba_nn<image_accessor_type, interpolator_type>
|
837 | 879 | image_span_gen_type;
|
|
0 commit comments