AGG/Cairo - fix pattern opacity

This commit is contained in:
artemp 2014-08-11 15:36:48 +01:00
parent 27ee642bbe
commit 201641a206
5 changed files with 22 additions and 54 deletions

View file

@ -36,8 +36,9 @@ namespace mapnik
class pattern_source : private mapnik::noncopyable class pattern_source : private mapnik::noncopyable
{ {
public: public:
pattern_source(image_data_32 const& pattern) pattern_source(image_data_32 const& pattern, double opacity = 1.0)
: pattern_(pattern) {} : pattern_(pattern),
opacity_(opacity) {}
unsigned int width() const unsigned int width() const
{ {
@ -50,13 +51,14 @@ public:
agg::rgba8 pixel(int x, int y) const agg::rgba8 pixel(int x, int y) const
{ {
unsigned c = pattern_(x,y); unsigned c = pattern_(x,y);
return agg::rgba8(c & 0xff, return agg::rgba8(static_cast<unsigned>((c & 0xff) * opacity_),
(c >> 8) & 0xff, static_cast<unsigned>(((c >> 8) & 0xff) * opacity_),
(c >> 16) & 0xff, static_cast<unsigned>(((c >> 16) & 0xff) * opacity_),
(c >> 24) & 0xff); static_cast<unsigned>(((c >> 24) & 0xff) * opacity_));
} }
private: private:
image_data_32 const& pattern_; image_data_32 const& pattern_;
double opacity_;
}; };
} }

View file

@ -121,7 +121,7 @@ private:
class cairo_pattern : private mapnik::noncopyable class cairo_pattern : private mapnik::noncopyable
{ {
public: public:
cairo_pattern(image_data_32 const& data) explicit cairo_pattern(image_data_32 const& data, double opacity = 1.0)
{ {
int pixels = data.width() * data.height(); int pixels = data.width() * data.height();
const unsigned int *in_ptr = data.getData(); const unsigned int *in_ptr = data.getData();
@ -135,10 +135,10 @@ public:
while (in_ptr < in_end) while (in_ptr < in_end)
{ {
unsigned int in = *in_ptr++; unsigned int in = *in_ptr++;
unsigned int r = (in >> 0) & 0xff; unsigned int r = static_cast<unsigned>(((in >> 0) & 0xff) * opacity);
unsigned int g = (in >> 8) & 0xff; unsigned int g = static_cast<unsigned>(((in >> 8) & 0xff) * opacity);
unsigned int b = (in >> 16) & 0xff; unsigned int b = static_cast<unsigned>(((in >> 16) & 0xff) * opacity);
unsigned int a = (in >> 24) & 0xff; unsigned int a = static_cast<unsigned>(((in >> 24) & 0xff) * opacity);
//r = r * a / 255; //r = r * a / 255;
//g = g * a / 255; //g = g * a / 255;

View file

@ -50,39 +50,6 @@
#include "agg_renderer_outline_image.h" #include "agg_renderer_outline_image.h"
#include "agg_conv_clip_polyline.h" #include "agg_conv_clip_polyline.h"
// boost
namespace {
class pattern_source : private mapnik::noncopyable
{
public:
pattern_source(mapnik::image_data_32 const& pattern)
: pattern_(pattern) {}
inline unsigned int width() const
{
return pattern_.width();
}
inline unsigned int height() const
{
return pattern_.height();
}
inline agg::rgba8 pixel(int x, int y) const
{
unsigned c = pattern_(x,y);
return agg::rgba8_pre(c & 0xff,
(c >> 8) & 0xff,
(c >> 16) & 0xff,
(c >> 24) & 0xff);
}
private:
mapnik::image_data_32 const& pattern_;
};
}
namespace mapnik { namespace mapnik {
template <typename T0, typename T1> template <typename T0, typename T1>
@ -117,7 +84,7 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
auto image_transform = get_optional<transform_type>(sym, keys::image_transform); auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform); if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform);
pat = render_pattern(*ras_ptr, **marker_ptr, image_tr, opacity); pat = render_pattern(*ras_ptr, **marker_ptr, image_tr, 1.0);
} }
if (!pat) return; if (!pat) return;
@ -133,7 +100,7 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
renderer_base ren_base(pixf); renderer_base ren_base(pixf);
agg::pattern_filter_bilinear_rgba8 filter; agg::pattern_filter_bilinear_rgba8 filter;
pattern_source source(*(*pat)); pattern_source source(*(*pat), opacity);
pattern_type pattern (filter,source); pattern_type pattern (filter,source);
renderer_type ren(ren_base, pattern); renderer_type ren(ren_base, pattern);
rasterizer_type ras(ren); rasterizer_type ras(ren);

View file

@ -73,7 +73,7 @@ void cairo_renderer<T>::process(line_pattern_symbolizer const& sym,
double opacity = get<value_double>(sym, keys::opacity, feature, common_.vars_,1.0); double opacity = get<value_double>(sym, keys::opacity, feature, common_.vars_,1.0);
if ((*marker)->is_bitmap()) if ((*marker)->is_bitmap())
{ {
pattern = std::make_unique<cairo_pattern>(**((*marker)->get_bitmap_data())); pattern = std::make_unique<cairo_pattern>(**((*marker)->get_bitmap_data()), opacity);
context_.set_line_width(height); context_.set_line_width(height);
} }
else else
@ -82,8 +82,8 @@ void cairo_renderer<T>::process(line_pattern_symbolizer const& sym,
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
auto image_transform = get_optional<transform_type>(sym, keys::image_transform); auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform); if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform);
image = render_pattern(ras, **marker, image_tr, opacity); image = render_pattern(ras, **marker, image_tr, 1.0);
pattern = std::make_unique<cairo_pattern>(*image); pattern = std::make_unique<cairo_pattern>(*image, opacity);
width = image->width(); width = image->width();
height = image->height(); height = image->height();
context_.set_line_width(height); context_.set_line_width(height);

View file

@ -47,7 +47,7 @@ void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym,
bool clip = get<bool>(sym, keys::clip, feature, common_.vars_, false); bool clip = get<bool>(sym, keys::clip, feature, common_.vars_, false);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0); double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double smooth = get<double>(sym, keys::smooth, feature, common_.vars_, 0.0); double smooth = get<double>(sym, keys::smooth, feature, common_.vars_, 0.0);
double opacity = get<double>(sym,keys::opacity, feature, common_.vars_, 1.0);
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
auto image_transform = get_optional<transform_type>(sym, keys::image_transform); auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform); if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform);
@ -83,7 +83,7 @@ void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym,
if ((*marker)->is_bitmap()) if ((*marker)->is_bitmap())
{ {
cairo_pattern pattern(**((*marker)->get_bitmap_data())); cairo_pattern pattern(**((*marker)->get_bitmap_data()), opacity);
pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_extend(CAIRO_EXTEND_REPEAT);
pattern.set_origin(offset_x, offset_y); pattern.set_origin(offset_x, offset_y);
context_.set_pattern(pattern); context_.set_pattern(pattern);
@ -91,9 +91,8 @@ void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym,
else else
{ {
mapnik::rasterizer ras; mapnik::rasterizer ras;
double opacity = get<double>(sym,keys::opacity, feature, common_.vars_, 1.0); image_ptr image = render_pattern(ras, **marker, image_tr, 1.0); //
image_ptr image = render_pattern(ras, **marker, image_tr, opacity); cairo_pattern pattern(*image, opacity);
cairo_pattern pattern(*image);
pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_extend(CAIRO_EXTEND_REPEAT);
pattern.set_origin(offset_x, offset_y); pattern.set_origin(offset_x, offset_y);
context_.set_pattern(pattern); context_.set_pattern(pattern);