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

36
COPYING
View file

@ -1,8 +1,8 @@
GNU LESSER GENERAL PUBLIC LICENSE GNU LESSER GENERAL PUBLIC LICENSE
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.
@ -10,7 +10,7 @@
as the successor of the GNU Library Public License, version 2, hence as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.] the version number 2.1.]
Preamble Preamble
The licenses for most software are designed to take away your The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public freedom to share and change it. By contrast, the GNU General Public
@ -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,8 +111,8 @@ 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
0. This License Agreement applies to any software library or other 0. This License Agreement applies to any software library or other
@ -146,7 +146,7 @@ such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does. and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's 1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an you conspicuously and appropriately publish on each copy an
@ -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
@ -432,7 +432,7 @@ decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing of all derivatives of our free software and of promoting the sharing
and reuse of software generally. and reuse of software generally.
NO WARRANTY NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
@ -455,8 +455,8 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 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

@ -2,8 +2,8 @@
// Anti-Grain Geometry - Version 2.4 // Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// //
// Permission to copy, use, modify, sell and distribute this software // Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies. // is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied // This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// //
@ -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)
// TODO: implement me! : color(c),offset(val) {}
} mapnik::color color;
double offset;
};
struct colorize_alpha : std::vector<color_stop>
{
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: