2012-03-19 22:42:44 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* This file is part of Mapnik (c++ mapping toolkit)
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011 Artem Pavlenko
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
// mapnik
|
|
|
|
#include <mapnik/image_compositing.hpp>
|
|
|
|
#include <mapnik/image_data.hpp>
|
|
|
|
|
2012-03-21 15:45:23 +00:00
|
|
|
// boost
|
|
|
|
#include <boost/assign/list_of.hpp>
|
|
|
|
#include <boost/bimap.hpp>
|
|
|
|
|
2012-03-19 22:42:44 +00:00
|
|
|
// agg
|
|
|
|
#include "agg_rendering_buffer.h"
|
|
|
|
#include "agg_rasterizer_scanline_aa.h"
|
|
|
|
#include "agg_scanline_u.h"
|
|
|
|
#include "agg_renderer_scanline.h"
|
|
|
|
#include "agg_pixfmt_rgba.h"
|
|
|
|
|
|
|
|
namespace mapnik
|
|
|
|
{
|
|
|
|
|
2012-03-21 15:45:23 +00:00
|
|
|
typedef boost::bimap<composite_mode_e, std::string> comp_op_lookup_type;
|
|
|
|
static const comp_op_lookup_type comp_lookup = boost::assign::list_of<comp_op_lookup_type::relation>
|
|
|
|
(clear,"clear")
|
|
|
|
(src,"src")
|
|
|
|
(dst,"dst")
|
2012-04-23 12:02:02 +00:00
|
|
|
(src_over,"src-over")
|
|
|
|
(dst_over,"dst-over")
|
|
|
|
(src_in,"src-in")
|
|
|
|
(dst_in,"dst-in")
|
|
|
|
(src_out,"src-out")
|
|
|
|
(dst_out,"dst-out")
|
|
|
|
(src_atop,"src-atop")
|
|
|
|
(dst_atop,"dst-atop")
|
2012-03-21 15:45:23 +00:00
|
|
|
(_xor,"xor")
|
|
|
|
(plus,"plus")
|
|
|
|
(minus,"minus")
|
|
|
|
(multiply,"multiply")
|
|
|
|
(screen,"screen")
|
|
|
|
(overlay,"overlay")
|
|
|
|
(darken,"darken")
|
|
|
|
(lighten,"lighten")
|
2012-04-23 12:02:02 +00:00
|
|
|
(color_dodge,"color-dodge")
|
|
|
|
(color_burn,"color-burn")
|
|
|
|
(hard_light,"hard-light")
|
|
|
|
(soft_light,"soft-light")
|
2012-03-21 15:45:23 +00:00
|
|
|
(difference,"difference")
|
|
|
|
(exclusion,"exclusion")
|
|
|
|
(contrast,"contrast")
|
|
|
|
(invert,"invert")
|
2012-05-25 09:35:43 +00:00
|
|
|
(invert_rgb,"invert-rgb")
|
|
|
|
(grain_merge,"grain-merge")
|
2012-05-29 14:09:33 +00:00
|
|
|
(grain_extract,"grain-extract")
|
2012-06-17 19:19:29 +00:00
|
|
|
(hue,"hue")
|
|
|
|
(saturation,"saturation")
|
|
|
|
(_color,"color")
|
2012-06-18 18:30:01 +00:00
|
|
|
(_value,"value")
|
2012-06-19 21:16:25 +00:00
|
|
|
(colorize_alpha,"colorize-alpha")
|
2012-05-25 09:35:43 +00:00
|
|
|
;
|
2012-03-21 15:45:23 +00:00
|
|
|
|
2012-04-18 14:37:14 +00:00
|
|
|
boost::optional<composite_mode_e> comp_op_from_string(std::string const& name)
|
2012-03-21 15:45:23 +00:00
|
|
|
{
|
2012-04-18 14:37:14 +00:00
|
|
|
boost::optional<composite_mode_e> mode;
|
2012-03-21 15:45:23 +00:00
|
|
|
comp_op_lookup_type::right_const_iterator right_iter = comp_lookup.right.find(name);
|
|
|
|
if (right_iter != comp_lookup.right.end())
|
|
|
|
{
|
2012-04-18 14:37:14 +00:00
|
|
|
mode.reset(right_iter->second);
|
2012-03-21 15:45:23 +00:00
|
|
|
}
|
2012-04-18 14:37:14 +00:00
|
|
|
return mode;
|
2012-03-21 15:45:23 +00:00
|
|
|
}
|
|
|
|
|
2012-07-06 00:06:41 +00:00
|
|
|
boost::optional<std::string> comp_op_to_string(composite_mode_e comp_op)
|
|
|
|
{
|
|
|
|
boost::optional<std::string> mode;
|
|
|
|
comp_op_lookup_type::left_const_iterator left_iter = comp_lookup.left.find(comp_op);
|
|
|
|
if (left_iter != comp_lookup.left.end())
|
|
|
|
{
|
|
|
|
mode.reset(left_iter->second);
|
|
|
|
}
|
|
|
|
return mode;
|
|
|
|
}
|
|
|
|
|
2012-03-19 22:42:44 +00:00
|
|
|
template <typename T1, typename T2>
|
2012-06-18 22:50:32 +00:00
|
|
|
void composite(T1 & dst, T2 & src, composite_mode_e mode,
|
2012-05-11 22:19:05 +00:00
|
|
|
float opacity,
|
2012-05-11 22:31:35 +00:00
|
|
|
int dx,
|
|
|
|
int dy,
|
2012-06-18 22:50:32 +00:00
|
|
|
bool premultiply_src)
|
2012-03-19 22:42:44 +00:00
|
|
|
{
|
|
|
|
typedef agg::rgba8 color;
|
2012-03-21 15:45:23 +00:00
|
|
|
typedef agg::order_rgba order;
|
2012-06-18 22:47:30 +00:00
|
|
|
typedef agg::comp_op_adaptor_rgba_pre<color, order> blender_type;
|
2012-03-19 22:42:44 +00:00
|
|
|
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
|
|
|
|
typedef agg::renderer_base<pixfmt_type> renderer_type;
|
2012-05-07 11:15:04 +00:00
|
|
|
|
2012-06-18 22:50:32 +00:00
|
|
|
agg::rendering_buffer dst_buffer(dst.getBytes(),dst.width(),dst.height(),dst.width() * 4);
|
|
|
|
agg::rendering_buffer src_buffer(src.getBytes(),src.width(),src.height(),src.width() * 4);
|
2012-05-07 11:15:04 +00:00
|
|
|
|
2012-06-18 22:50:32 +00:00
|
|
|
pixfmt_type pixf(dst_buffer);
|
2012-03-21 15:45:23 +00:00
|
|
|
pixf.comp_op(static_cast<agg::comp_op_e>(mode));
|
2012-06-18 22:50:32 +00:00
|
|
|
|
|
|
|
agg::pixfmt_rgba32 pixf_mask(src_buffer);
|
2012-04-20 13:53:11 +00:00
|
|
|
if (premultiply_src) pixf_mask.premultiply();
|
2012-03-19 22:42:44 +00:00
|
|
|
renderer_type ren(pixf);
|
2012-06-19 12:43:15 +00:00
|
|
|
ren.blend_from(pixf_mask,0,dx,dy,unsigned(255*opacity));
|
2012-05-11 09:55:58 +00:00
|
|
|
}
|
|
|
|
|
2012-06-18 22:50:32 +00:00
|
|
|
template void composite<mapnik::image_data_32,mapnik::image_data_32>(mapnik::image_data_32&, mapnik::image_data_32& ,composite_mode_e, float, int, int, bool);
|
2012-03-19 22:42:44 +00:00
|
|
|
|
|
|
|
}
|