Merge branch 'master' of github.com:mapnik/mapnik

This commit is contained in:
Dane Springmeyer 2013-03-22 17:58:49 -07:00
commit aaecd92fb6
10 changed files with 165 additions and 55 deletions

22
COPYING
View file

@ -2,7 +2,7 @@
Version 2.1, February 1999 Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc. Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be author's reputation will not be affected by problems that might be
introduced by others. introduced by others.
Finally, software patents pose a constant threat to the existence of Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a effectively restrict the users of a free program by obtaining a
@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The "work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must former contains code derived from the library, whereas the latter must
be combined with the library in order to run. be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@ -158,7 +158,7 @@ Library.
You may charge a fee for the physical act of transferring a copy, You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a and you may at your option offer warranty protection in exchange for a
fee. fee.
2. You may modify your copy or copies of the Library or any portion 2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1 distribute such modifications or work under the terms of Section 1
@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in that version instead if you wish.) Do not make any other change in
these notices. these notices.
Once this change is made in a given copy, it is irreversible for Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy. subsequent copies and derivative works made from that copy.
@ -267,7 +267,7 @@ Library will still fall under Section 6.)
distribute the object code for the work under the terms of Section 6. distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6, Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself. whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or 6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work work containing portions of the Library, and distribute that work
@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you use both them and the Library together in an executable that you
distribute. distribute.
7. You may place library facilities that are a work based on the 7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined facilities not covered by this License, and distribute such a combined
@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein. restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with You are not responsible for enforcing compliance by third parties with
this License. this License.
11. If, as a consequence of a court judgment or allegation of patent 11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues), infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or conditions are imposed on you (whether by court order, agreement or
@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by license version number, you may choose any version ever published by
the Free Software Foundation. the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free 14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these, programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is write to the author to ask for permission. For software which is
@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES. DAMAGES.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest If you develop a new library, and you want it to be of the greatest
@ -485,7 +485,7 @@ convey the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.

View file

@ -7,7 +7,7 @@ To configure and build Mapnik do:
./configure ./configure
make make
NOTE: the above will not work on windows, rather see https://github.com/mapnik/mapnik/wiki/BuildingOnWindows NOTE: the above will not work on windows, rather see https://github.com/mapnik/mapnik/wiki/WindowsInstallation
Then to run the tests locally (without needing to install): Then to run the tests locally (without needing to install):

View file

@ -40,6 +40,7 @@ namespace agg
double operator() (double x) const double operator() (double x) const
{ {
if (x == 0.0) return 0.0;
return pow(x, m_gamma); return pow(x, m_gamma);
} }
@ -122,6 +123,3 @@ namespace agg
} }
#endif #endif

View file

@ -32,6 +32,7 @@
#include <boost/variant/static_visitor.hpp> #include <boost/variant/static_visitor.hpp>
#include <boost/gil/gil_all.hpp> #include <boost/gil/gil_all.hpp>
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
#include <boost/foreach.hpp>
// agg // agg
#include "agg_basics.h" #include "agg_basics.h"
@ -39,7 +40,7 @@
#include "agg_pixfmt_rgba.h" #include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h" #include "agg_scanline_u.h"
#include "agg_blur.h" #include "agg_blur.h"
#include "agg_gradient_lut.h"
// stl // stl
#include <cmath> #include <cmath>
@ -404,6 +405,84 @@ void apply_filter(Src & src, agg_stack_blur const& op)
agg::stack_blur_rgba32(pixf,op.rx,op.ry); agg::stack_blur_rgba32(pixf,op.rx,op.ry);
} }
template <typename Src>
void apply_filter(Src & src, colorize_alpha const& op)
{
using namespace boost::gil;
agg::gradient_lut<agg::color_interpolator<agg::rgba8> > grad_lut;
grad_lut.remove_all();
std::size_t size = op.size();
if (size < 2) return;
double step = 1.0/(size-1);
double offset = 0.0;
BOOST_FOREACH( mapnik::filter::color_stop const& stop, op)
{
mapnik::color const& c = stop.color;
double stop_offset = stop.offset;
if (stop_offset == 0)
{
stop_offset = offset;
}
grad_lut.add_color(stop_offset, agg::rgba(c.red()/256.0,
c.green()/256.0,
c.blue()/256.0,
c.alpha()/256.0));
offset += step;
}
grad_lut.build_lut();
rgba8_view_t src_view = rgba8_view(src);
for (int y=0; y<src_view.height(); ++y)
{
rgba8_view_t::x_iterator src_it = src_view.row_begin(y);
for (int x=0; x<src_view.width(); ++x)
{
uint8_t & r = get_color(src_it[x], red_t());
uint8_t & g = get_color(src_it[x], green_t());
uint8_t & b = get_color(src_it[x], blue_t());
uint8_t & a = get_color(src_it[x], alpha_t());
if ( a > 0)
{
agg::rgba8 c = grad_lut[a];
r = (c.r * a + 255) >> 8;
g = (c.g * a + 255) >> 8;
b = (c.b * a + 255) >> 8;
#if 0
// rainbow
r = 0;
g = 0;
b = 0;
if (a < 64)
{
g = a * 4;
b = 255;
}
else if (a >= 64 && a < 128)
{
g = 255;
b = 255 - ((a - 64) * 4);
}
else if (a >= 128 && a < 192)
{
r = (a - 128) * 4;
g = 255;
}
else // >= 192
{
r = 255;
g = 255 - ((a - 192) * 4);
}
r = (r * a + 255) >> 8;
g = (g * a + 255) >> 8;
b = (b * a + 255) >> 8;
#endif
}
}
}
}
template <typename Src> template <typename Src>
void apply_filter(Src & src, hsla const& transform) void apply_filter(Src & src, hsla const& transform)
{ {

View file

@ -25,16 +25,40 @@
// boost // boost
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
// mapnik // mapnik
#include <mapnik/css_color_grammar.hpp> #include <mapnik/css_color_grammar.hpp>
#include <mapnik/image_filter.hpp>
// stl // stl
#include <vector> #include <vector>
BOOST_FUSION_ADAPT_STRUCT(
mapnik::filter::color_stop,
(mapnik::color, color )
(double, offset)
)
namespace mapnik { namespace mapnik {
namespace qi = boost::spirit::qi; namespace qi = boost::spirit::qi;
struct percent_offset_impl
{
template <typename T>
struct result
{
typedef double type;
};
double operator() (double val) const
{
double result = std::abs(val/100.0);
if (result > 1.0) result = 1.0;
return result;
}
};
template <typename Iterator, typename ContType> template <typename Iterator, typename ContType>
struct image_filter_grammar : struct image_filter_grammar :
qi::grammar<Iterator, ContType(), qi::ascii::space_type> qi::grammar<Iterator, ContType(), qi::ascii::space_type>
@ -45,10 +69,12 @@ struct image_filter_grammar :
qi::rule<Iterator, qi::locals<int,int>, void(ContType&), qi::ascii::space_type> agg_blur_filter; qi::rule<Iterator, qi::locals<int,int>, void(ContType&), qi::ascii::space_type> agg_blur_filter;
qi::rule<Iterator, qi::locals<double,double,double,double,double,double,double,double>, qi::rule<Iterator, qi::locals<double,double,double,double,double,double,double,double>,
void(ContType&), qi::ascii::space_type> hsla_filter; void(ContType&), qi::ascii::space_type> hsla_filter;
qi::rule<Iterator, qi::locals<mapnik::color,mapnik::color>, void(ContType&), qi::ascii::space_type> colorize_alpha_filter; qi::rule<Iterator, qi::locals<mapnik::filter::colorize_alpha, mapnik::filter::color_stop>, void(ContType&), qi::ascii::space_type> colorize_alpha_filter;
qi::rule<Iterator, qi::ascii::space_type> no_args; qi::rule<Iterator, qi::ascii::space_type> no_args;
qi::uint_parser< unsigned, 10, 1, 3 > radius_; qi::uint_parser< unsigned, 10, 1, 3 > radius_;
css_color_grammar<Iterator> css_color_; css_color_grammar<Iterator> css_color_;
qi::rule<Iterator,void(mapnik::filter::color_stop &),qi::ascii::space_type> color_stop_offset;
phoenix::function<percent_offset_impl> percent_offset;
}; };
} }

View file

@ -98,12 +98,18 @@ struct hsla
double a1; double a1;
}; };
struct colorize_alpha struct color_stop
{ {
colorize_alpha(mapnik::color const& c0, mapnik::color const& c1) color_stop() {}
color_stop(mapnik::color const& c, double val = 0.0)
: color(c),offset(val) {}
mapnik::color color;
double offset;
};
struct colorize_alpha : std::vector<color_stop>
{ {
// TODO: implement me! colorize_alpha() {}
}
}; };
typedef boost::variant<filter::blur, typedef boost::variant<filter::blur,

View file

@ -344,11 +344,10 @@ void agg_renderer<T>::render_marker(pixel_position const& pos,
{ {
double width = (*marker.get_bitmap_data())->width(); double width = (*marker.get_bitmap_data())->width();
double height = (*marker.get_bitmap_data())->height(); 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 && tr.is_identity()) if (std::fabs(1.0 - scale_factor_) < 0.001 && tr.is_identity())
{ {
double cx = 0.5 * width;
double cy = 0.5 * height;
composite(current_buffer_->data(), **marker.get_bitmap_data(), composite(current_buffer_->data(), **marker.get_bitmap_data(),
comp_op, opacity, comp_op, opacity,
boost::math::iround(pos.x - cx), boost::math::iround(pos.x - cx),

View file

@ -629,21 +629,24 @@ void cairo_renderer_base::render_marker(pixel_position const& pos,
mapnik::svg_path_ptr vmarker = *marker.get_vector_data(); mapnik::svg_path_ptr vmarker = *marker.get_vector_data();
if (vmarker) if (vmarker)
{ {
agg::trans_affine marker_tr = tr;
marker_tr *=agg::trans_affine_scaling(scale_factor_);
agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes(); agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes();
render_vector_marker(context_, pos, *vmarker, attributes, tr, opacity, recenter); render_vector_marker(context_, pos, *vmarker, attributes, marker_tr, opacity, recenter);
} }
} }
else if (marker.is_bitmap()) else if (marker.is_bitmap())
{ {
agg::trans_affine matrix = tr;
double width = (*marker.get_bitmap_data())->width(); double width = (*marker.get_bitmap_data())->width();
double height = (*marker.get_bitmap_data())->height(); double height = (*marker.get_bitmap_data())->height();
double cx = 0.5 * width; double cx = 0.5 * width;
double cy = 0.5 * height; double cy = 0.5 * height;
matrix *= agg::trans_affine_translation( agg::trans_affine marker_tr;
boost::math::iround(pos.x - cx), marker_tr *= agg::trans_affine_translation(-cx,-cy);
boost::math::iround(pos.y - cy)); marker_tr *= tr;
context_.add_image(matrix, **marker.get_bitmap_data(), opacity); marker_tr *= agg::trans_affine_scaling(scale_factor_);
marker_tr *= agg::trans_affine_translation(pos.x,pos.y);
context_.add_image(marker_tr, **marker.get_bitmap_data(), opacity);
} }
} }
@ -689,7 +692,7 @@ void cairo_renderer_base::process(point_symbolizer const& sym,
double dx = 0.5 * (*marker)->width(); double dx = 0.5 * (*marker)->width();
double dy = 0.5 * (*marker)->height(); double dy = 0.5 * (*marker)->height();
agg::trans_affine tr = agg::trans_affine_scaling(scale_factor_); agg::trans_affine tr;
evaluate_transform(tr, feature, sym.get_image_transform()); evaluate_transform(tr, feature, sym.get_image_transform());
box2d<double> label_ext (-dx, -dy, dx, dy); box2d<double> label_ext (-dx, -dy, dx, dy);
label_ext *= tr; label_ext *= tr;
@ -728,15 +731,9 @@ void cairo_renderer_base::process(shield_symbolizer const& sym,
pixel_position pos = helper.get_marker_position(placements[ii]); pixel_position pos = helper.get_marker_position(placements[ii]);
pos.x += 0.5 * helper.get_marker_width(); pos.x += 0.5 * helper.get_marker_width();
pos.y += 0.5 * helper.get_marker_height(); pos.y += 0.5 * helper.get_marker_height();
double dx = 0.5 * helper.get_marker_width();
double dy = 0.5 * helper.get_marker_height();
agg::trans_affine marker_tr = agg::trans_affine_translation(-dx,-dy);
marker_tr *= agg::trans_affine_scaling(scale_factor_);
marker_tr *= agg::trans_affine_translation(dx,dy);
marker_tr *= helper.get_image_transform();
render_marker(pos, render_marker(pos,
helper.get_marker(), helper.get_marker(),
marker_tr, helper.get_image_transform(),
sym.get_opacity()); sym.get_opacity());
context_.add_text(placements[ii], face_manager_, font_manager_, scale_factor_); context_.add_text(placements[ii], face_manager_, font_manager_, scale_factor_);

View file

@ -22,7 +22,6 @@
// mapnik // mapnik
#include <mapnik/image_filter_grammar.hpp> #include <mapnik/image_filter_grammar.hpp>
#include <mapnik/image_filter.hpp>
// boost // boost
#include <boost/version.hpp> #include <boost/version.hpp>
@ -58,7 +57,7 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
using boost::spirit::ascii::string; using boost::spirit::ascii::string;
using phoenix::push_back; using phoenix::push_back;
using phoenix::construct; using phoenix::construct;
using phoenix::at_c;
#if BOOST_VERSION >= 104700 #if BOOST_VERSION >= 104700
using qi::no_skip; using qi::no_skip;
start = -(filter % no_skip[*char_(", ")]) start = -(filter % no_skip[*char_(", ")])
@ -110,13 +109,19 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
[push_back(_r1, construct<mapnik::filter::hsla>(_a,_b,_c,_d,_e,_f,_g,_h))] [push_back(_r1, construct<mapnik::filter::hsla>(_a,_b,_c,_d,_e,_f,_g,_h))]
; ;
colorize_alpha_filter = lit("colorize-alpha") colorize_alpha_filter = lit("colorize-alpha")[_a = construct<mapnik::filter::colorize_alpha>()]
>> lit('(') >> lit('(')
>> css_color_[_a = _1] >> lit(',') >> (css_color_[at_c<0>(_b) = _1, at_c<1>(_b) = 0]
>> css_color_[_b = _1] >> lit(')') >> -color_stop_offset(_b)) [push_back(_a,_b)]
[push_back(_r1,construct<mapnik::filter::colorize_alpha>(_a,_b))] >> +(lit(',') >> css_color_[at_c<0>(_b) =_1,at_c<1>(_b) = 0]
>> -color_stop_offset(_b))[push_back(_a,_b)]
>> lit(')') [push_back(_r1,_a)]
; ;
color_stop_offset = (double_ >> lit('%'))[at_c<1>(_r1) = percent_offset(_1)]
|
double_[at_c<1>(_r1) = _1]
;
no_args = -(lit('(') >> lit(')')); no_args = -(lit('(') >> lit(')'));
} }

View file

@ -125,7 +125,7 @@ def render(config, width, height, bbox, scale_factor, quiet=False, overwrite_fai
except Exception, e: except Exception, e:
sys.stderr.write(e.message + '\n') sys.stderr.write(e.message + '\n')
fail(actual_agg,expected_agg,str(e.message)) fail(actual_agg,expected_agg,str(e.message))
return return m
if not quiet: if not quiet:
print "\"%s\" with agg..." % (postfix), print "\"%s\" with agg..." % (postfix),
try: try: