From 195b8ad88756c06a22c00b657ca2ab81abec3700 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 17 Jul 2012 17:10:24 +0100 Subject: [PATCH] + affine transform for raster markers - #1279 --- src/agg/agg_renderer.cpp | 103 +++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 31 deletions(-) diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index c7a480780..bff971757 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -42,7 +42,11 @@ #include "agg_rendering_buffer.h" #include "agg_pixfmt_rgba.h" #include "agg_scanline_u.h" - +#include "agg_image_filters.h" +#include "agg_trans_bilinear.h" +#include "agg_span_allocator.h" +#include "agg_image_accessors.h" +#include "agg_span_image_filter_rgba.h" // boost #include #include @@ -264,24 +268,24 @@ template void agg_renderer::render_marker(pixel_position const& pos, marker const& marker, agg::trans_affine const& tr, double opacity, composite_mode_e comp_op) { + typedef agg::rgba8 color_type; + typedef agg::order_rgba order_type; + typedef agg::pixel32_type pixel_type; + typedef agg::comp_op_adaptor_rgba blender_type; // comp blender + typedef agg::pixfmt_custom_blend_rgba pixfmt_comp_type; + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_type; + + ras_ptr->reset(); + ras_ptr->gamma(agg::gamma_power()); + agg::scanline_u8 sl; + agg::rendering_buffer buf(current_buffer_->raw_data(), width_, height_, width_ * 4); + pixfmt_comp_type pixf(buf); + pixf.comp_op(static_cast(comp_op)); + renderer_base renb(pixf); + if (marker.is_vector()) { - typedef agg::rgba8 color_type; - typedef agg::order_rgba order_type; - typedef agg::pixel32_type pixel_type; - typedef agg::comp_op_adaptor_rgba blender_type; // comp blender - typedef agg::pixfmt_custom_blend_rgba pixfmt_comp_type; - typedef agg::renderer_base renderer_base; - typedef agg::renderer_scanline_aa_solid renderer_type; - - ras_ptr->reset(); - ras_ptr->gamma(agg::gamma_power()); - agg::scanline_u8 sl; - agg::rendering_buffer buf(current_buffer_->raw_data(), width_, height_, width_ * 4); - pixfmt_comp_type pixf(buf); - pixf.comp_op(static_cast(comp_op)); - renderer_base renb(pixf); - box2d const& bbox = (*marker.get_vector_data())->bounding_box(); coord c = bbox.center(); // center the svg marker on '0,0' @@ -304,12 +308,12 @@ void agg_renderer::render_marker(pixel_position const& pos, marker const& mar } else { - double w = (*marker.get_bitmap_data())->width(); - double h = (*marker.get_bitmap_data())->height(); - double cx = 0.5 * w; - double cy = 0.5 * h; + double width = (*marker.get_bitmap_data())->width(); + double height = (*marker.get_bitmap_data())->height(); + double cx = 0.5 * width; + double cy = 0.5 * height; - if (std::fabs(1.0 - scale_factor_) < 0.001) + if (std::fabs(1.0 - scale_factor_) < 0.001 && tr.is_identity()) { composite(current_buffer_->data(), **marker.get_bitmap_data(), comp_op, opacity, @@ -319,15 +323,52 @@ void agg_renderer::render_marker(pixel_position const& pos, marker const& mar } else { - double scaled_width = w * scale_factor_; - double scaled_height = h * scale_factor_; - image_data_32 buf(std::ceil(scaled_width),std::ceil(scaled_height)); - scale_image_agg(buf, **marker.get_bitmap_data(), SCALING_BILINEAR, scale_factor_); - composite(current_buffer_->data(), buf, - comp_op, opacity, - boost::math::iround(pos.x - 0.5*scaled_width), - boost::math::iround(pos.y - 0.5*scaled_height), - false); + + double p[8]; + double x0 = pos.x - 0.5 * width; + double y0 = pos.y - 0.5 * height; + p[0] = x0; p[1] = y0; + p[2] = x0 + width; p[3] = y0; + p[4] = x0 + width; p[5] = y0 + height; + p[6] = x0; p[7] = y0 + height; + + agg::trans_affine marker_tr; + + marker_tr *= agg::trans_affine_translation(-pos.x,-pos.y); + marker_tr *= tr; + marker_tr *= agg::trans_affine_scaling(scale_factor_); + marker_tr *= agg::trans_affine_translation(pos.x,pos.y); + + marker_tr.transform(&p[0], &p[1]); + marker_tr.transform(&p[2], &p[3]); + marker_tr.transform(&p[4], &p[5]); + marker_tr.transform(&p[6], &p[7]); + + ras_ptr->move_to_d(p[0],p[1]); + ras_ptr->line_to_d(p[2],p[3]); + ras_ptr->line_to_d(p[4],p[5]); + ras_ptr->line_to_d(p[6],p[7]); + + + agg::span_allocator sa; + agg::image_filter_bilinear filter_kernel; + agg::image_filter_lut filter(filter_kernel, false); + + image_data_32 const& src = **marker.get_bitmap_data(); + agg::rendering_buffer marker_buf((unsigned char *)src.getBytes(), + src.width(), + src.height(), + src.width()*4); + agg::pixfmt_rgba32_pre pixf(marker_buf); + + typedef agg::image_accessor_clone img_accessor_type; + typedef agg::span_interpolator_linear interpolator_type; + typedef agg::span_image_filter_rgba_2x2 span_gen_type; + img_accessor_type ia(pixf); + interpolator_type interpolator(agg::trans_affine(p, 0, 0, width, height) ); + span_gen_type sg(ia, interpolator, filter); + agg::render_scanlines_aa(*ras_ptr, sl, renb, sa, sg); } } }