image_filters_grammar_x3 - initial port to x3 + remove unused grammars (css_color_grammar,image_filter_grammar)

This commit is contained in:
artemp 2016-02-08 12:49:13 +01:00
parent b84eb8f2b0
commit 2a3248cfaa
9 changed files with 384 additions and 275 deletions

View file

@ -1,86 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef MAPNIK_IMAGE_FILITER_GRAMMAR_HPP
#define MAPNIK_IMAGE_FILITER_GRAMMAR_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/css_color_grammar.hpp>
#include <mapnik/color.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
#pragma GCC diagnostic pop
// stl
#include <cmath>
namespace mapnik {
namespace filter {
struct color_stop;
struct colorize_alpha;
}
namespace qi = boost::spirit::qi;
struct percent_offset_impl
{
template <typename T>
struct result
{
using type = double;
};
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>
struct image_filter_grammar :
qi::grammar<Iterator, ContType(), qi::ascii::space_type>
{
image_filter_grammar();
qi::rule<Iterator, ContType(), qi::ascii::space_type> start;
qi::rule<Iterator, ContType(), qi::ascii::space_type> 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>,
void(ContType&), qi::ascii::space_type> scale_hsla_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::uint_parser< unsigned, 10, 1, 3 > radius_;
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;
qi::rule<Iterator, qi::locals<color>, void(ContType&), qi::ascii::space_type> color_to_alpha_filter;
};
}
#endif // MAPNIK_IMAGE_FILITER_PARSER_HPP

View file

@ -1,141 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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_filter_types.hpp>
#include <mapnik/image_filter_grammar.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/phoenix.hpp>
#pragma GCC diagnostic pop
BOOST_FUSION_ADAPT_STRUCT(
mapnik::filter::color_stop,
(mapnik::color, color )
(double, offset)
)
namespace mapnik {
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
template <typename Iterator, typename ContType>
image_filter_grammar<Iterator,ContType>::image_filter_grammar()
: image_filter_grammar::base_type(start)
{
qi::lit_type lit;
qi::_val_type _val;
qi::_1_type _1;
qi::_a_type _a;
qi::_b_type _b;
qi::_c_type _c;
qi::_d_type _d;
qi::_e_type _e;
qi::_f_type _f;
qi::_g_type _g;
qi::_h_type _h;
qi::_r1_type _r1;
qi::double_type double_;
using phoenix::push_back;
using phoenix::construct;
using phoenix::at_c;
start = -(filter % *lit(','))
;
filter =
lit("emboss") >> no_args [push_back(_val,construct<mapnik::filter::emboss>())]
|
lit("blur") >> no_args [push_back(_val,construct<mapnik::filter::blur>())]
|
lit("gray") >> no_args [push_back(_val,construct<mapnik::filter::gray>())]
|
lit("edge-detect") >> no_args [push_back(_val,construct<mapnik::filter::edge_detect>())]
|
lit("sobel") >> no_args [push_back(_val,construct<mapnik::filter::sobel>())]
|
lit("sharpen") >> no_args [push_back(_val,construct<mapnik::filter::sharpen>())]
|
lit("x-gradient") >> no_args [push_back(_val,construct<mapnik::filter::x_gradient>())]
|
lit("y-gradient") >> no_args [push_back(_val,construct<mapnik::filter::y_gradient>())]
|
lit("invert") >> no_args [push_back(_val,construct<mapnik::filter::invert>())]
|
lit("color-blind-protanope") >> no_args [push_back(_val,construct<mapnik::filter::color_blind_protanope>())]
|
lit("color-blind-deuteranope") >> no_args [push_back(_val,construct<mapnik::filter::color_blind_deuteranope>())]
|
lit("color-blind-tritanope") >> no_args [push_back(_val,construct<mapnik::filter::color_blind_tritanope>())]
|
agg_blur_filter(_val)
|
scale_hsla_filter(_val)
|
colorize_alpha_filter(_val)
|
color_to_alpha_filter(_val)
;
agg_blur_filter = (lit("agg-stack-blur")[_a = 1, _b = 1]
>> -( lit('(') >> -( radius_[_a = _1][_b = _1]
>> -(lit(',') >> radius_[_b = _1])) >> lit(')')))
[push_back(_r1, construct<mapnik::filter::agg_stack_blur>(_a,_b))]
;
scale_hsla_filter = lit("scale-hsla")
>> lit('(')
>> double_[_a = _1] >> lit(',') >> double_[_b = _1] >> lit(',')
>> double_[_c = _1] >> lit(',') >> double_[_d = _1] >> lit(',')
>> double_[_e = _1] >> lit(',') >> double_[_f = _1] >> lit(',')
>> double_[_g = _1] >> lit(',') >> double_[_h = _1] >> lit(')')
[push_back(_r1, construct<mapnik::filter::scale_hsla>(_a,_b,_c,_d,_e,_f,_g,_h))]
;
colorize_alpha_filter = lit("colorize-alpha")[_a = construct<mapnik::filter::colorize_alpha>()]
>> lit('(')
>> (css_color_[at_c<0>(_b) = _1, at_c<1>(_b) = 0]
>> -color_stop_offset(_b)) [push_back(_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]
;
color_to_alpha_filter = lit("color-to-alpha")
>> lit('(')
>> css_color_[_a = _1]
>> lit(')')
[push_back(_r1,construct<mapnik::filter::color_to_alpha>(_a))]
;
no_args = -(lit('(') >> lit(')'));
}
}

View file

@ -0,0 +1,56 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2016 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
*
*****************************************************************************/
#ifndef MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP
#define MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP
//#include <mapnik/image_filter.hpp>
#include <mapnik/image_filter_types.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/home/x3.hpp>
#pragma GCC diagnostic pop
namespace mapnik
{
namespace x3 = boost::spirit::x3;
namespace image_filter
{
struct image_filter_class;
using image_filter_grammar_type = x3::rule<image_filter_class, std::vector<filter::filter_type> >;
BOOST_SPIRIT_DECLARE(image_filter_grammar_type);
}}
namespace mapnik {
image_filter::image_filter_grammar_type image_filter_grammar();
}
#endif // MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP

View file

@ -0,0 +1,260 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2016 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
*
*****************************************************************************/
#ifndef MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP
#define MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP
#include <mapnik/image_filter_grammar_x3.hpp>
#include <mapnik/image_filter_types.hpp>
#include <mapnik/css_color_grammar_x3.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#pragma GCC diagnostic pop
BOOST_FUSION_ADAPT_STRUCT(
mapnik::filter::scale_hsla,
(double, h0)
(double, h1)
(double, s0)
(double, s1)
(double, l0)
(double, l1)
(double, a0)
(double, a1)
)
BOOST_FUSION_ADAPT_STRUCT(
mapnik::filter::color_stop,
(mapnik::color, color )
(double, offset)
)
BOOST_FUSION_ADAPT_STRUCT(
mapnik::filter::color_to_alpha,
(mapnik::color, color)
)
namespace mapnik {
namespace x3 = boost::spirit::x3;
namespace image_filter {
using x3::lit;
using x3::uint_parser;
using x3::hex;
using x3::symbols;
using x3::omit;
using x3::attr;
using x3::double_;
using x3::no_case;
using x3::no_skip;
using x3::char_;
auto push_back = [](auto& ctx)
{
_val(ctx).push_back(_attr(ctx));
};
auto set_rx_ry = [](auto & ctx)
{
_val(ctx).rx = _val(ctx).ry = _attr(ctx);
};
auto set_ry = [](auto & ctx)
{
_val(ctx).ry = _attr(ctx);
};
auto offset_value = [](auto & ctx)
{
_val(ctx) = _attr(ctx);
};
auto percent = [](auto & ctx)
{
double val = std::abs(_val(ctx)/100.0);
if (val > 1.0) val = 1.0;
_val(ctx) = val;
};
x3::uint_parser<unsigned, 10, 1, 3> radius;
// Import the expression rule
namespace { auto const& css_color = color_grammar(); }
// starting rule
image_filter_grammar_type const start("start");
// rules
x3::rule<class filter_class, filter::filter_type > const filter("filter");
x3::rule<class emboss_class, filter::emboss> const emboss_filter("emboss");
x3::rule<class blur_class, filter::blur> const blur_filter("blur");
x3::rule<class gray_class, filter::gray> const gray_filter("gray");
x3::rule<class edge_detect_class, filter::edge_detect> const edge_detect_filter("edge-detect");
x3::rule<class sobel_class, filter::sobel> const sobel_filter("sobel");
x3::rule<class sharpen_class, filter::sharpen> const sharpen_filter("sharpen");
x3::rule<class x_gradient_class, filter::x_gradient> const x_gradient_filter("x-gradient");
x3::rule<class y_gradient_class, filter::y_gradient> const y_gradient_filter("y-gradient");
x3::rule<class invert_class, filter::invert> const invert_filter("invert");
x3::rule<class color_blind_protanope_class, filter::color_blind_protanope> const color_blind_protanope_filter("color-blind-protanope");
x3::rule<class color_blind_deuteranope_class, filter::color_blind_deuteranope> const color_blind_deuteranope_filter("color-blind-deuteranope");
x3::rule<class color_blind_tritanope_class, filter::color_blind_tritanope> const color_blind_tritanope_filter("color-blind-tritanope");
x3::rule<class agg_blur_class, filter::agg_stack_blur> const agg_blur_filter("agg blur filter");
x3::rule<class scale_hsla_class, filter::scale_hsla> const scale_hsla_filter("scale-hsla");
x3::rule<class colorize_alpha_class, filter::colorize_alpha> const colorize_alpha_filter("colorize-alpha");
x3::rule<class color_stop_class, filter::color_stop> const color_stop("color-stop");
x3::rule<class offset_class, double> const offset("color-stop-offset");
x3::rule<class color_to_alpha_class, filter::color_to_alpha> const color_to_alpha_filter("color-to-alpha");
auto const no_args = -(lit('(') > lit(')'));
auto const start_def = -(filter[push_back] % *lit(','));
auto const filter_def = (emboss_filter
|
blur_filter
|
gray_filter
|
edge_detect_filter
|
sobel_filter
|
sharpen_filter
|
x_gradient_filter
|
y_gradient_filter
|
invert_filter
|
color_blind_protanope_filter
|
color_blind_deuteranope_filter
|
color_blind_tritanope_filter
|
agg_blur_filter
|
scale_hsla_filter
|
colorize_alpha_filter
|
color_to_alpha_filter
)
;
auto const emboss_filter_def = lit("emboss") > no_args;
auto const blur_filter_def = lit("blur") > no_args;
auto const gray_filter_def = lit("gray") > no_args;
auto const edge_detect_filter_def = lit("edge-detect") > no_args;
auto const sobel_filter_def = lit("sobel") > no_args;
auto const sharpen_filter_def = lit("sharpen") > no_args;
auto const x_gradient_filter_def = lit("x-gradient") > no_args;
auto const y_gradient_filter_def = lit("y-gradient") > no_args;
auto const invert_filter_def = lit("invert") > no_args;
auto const color_blind_protanope_filter_def = lit("color-blind-protanope") > no_args;
auto const color_blind_deuteranope_filter_def = lit("color-blind-deuteranope") > no_args;
auto const color_blind_tritanope_filter_def = lit("color-blind-tritanope") > no_args;
auto const agg_blur_filter_def = lit("agg-stack-blur")
> -(lit('(') > -(radius[set_rx_ry] > -(lit(',') > radius[set_ry])) > lit(')'));
auto const scale_hsla_filter_def = lit("scale-hsla") > lit('(')
> double_ > ','
> double_ > ','
> double_ > ','
> double_ > ','
> double_ > ','
> double_ > ','
> double_ > ','
> double_ > ')' ;
auto const offset_def = double_[offset_value] > -lit('%')[percent];
auto const color_stop_def = css_color > -offset;
auto const colorize_alpha_filter_def = lit("colorize-alpha")
> lit('(')
> color_stop > *(lit(',') > color_stop)
> lit(')') ;
auto const color_to_alpha_filter_def = lit("color-to-alpha") > lit('(')
> -css_color > lit(')');
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
BOOST_SPIRIT_DEFINE(
start,
filter,
emboss_filter,
blur_filter,
gray_filter,
edge_detect_filter,
sobel_filter,
sharpen_filter,
x_gradient_filter,
y_gradient_filter,
invert_filter,
agg_blur_filter,
color_blind_protanope_filter,
color_blind_deuteranope_filter,
color_blind_tritanope_filter,
scale_hsla_filter,
colorize_alpha_filter,
color_stop,
offset,
color_to_alpha_filter
);
#pragma GCC diagnostic pop
} // image_filter
image_filter::image_filter_grammar_type image_filter_grammar()
{
return image_filter::start;
}
} //ns mapnik
#endif //MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP

View file

@ -56,30 +56,35 @@ struct y_gradient : image_filter_base {};
struct invert : image_filter_base {};
// http://vision.psychol.cam.ac.uk/jdmollon/papers/colourmaps.pdf
struct color_blind_protanope : image_filter_base
struct color_blind_filter : image_filter_base
{
const double x = 0.7465;
const double y = 0.2535;
const double m = 1.273463;
const double yint = -0.073894;
color_blind_filter(double x_, double y_, double m_, double yint_)
: x(x_), y(y_), m(m_), yint(yint_) {}
double x;
double y;
double m;
double yint;
};
struct color_blind_deuteranope : image_filter_base
struct color_blind_protanope : color_blind_filter
{
const double x = 1.4;
const double y = -0.4;
const double m = 0.968437;
const double yint = 0.003331;
color_blind_protanope()
: color_blind_filter(0.7465, 0.2535, 1.273463, -0.073894) {}
};
struct color_blind_tritanope : image_filter_base
struct color_blind_deuteranope : color_blind_filter
{
const double x = 0.1748;
const double y = 0.0;
const double m = 0.062921;
const double yint = 0.292119;
color_blind_deuteranope()
: color_blind_filter(1.4, -0.4, 0.968437, 0.003331) {}
};
struct color_blind_tritanope : color_blind_filter
{
color_blind_tritanope()
: color_blind_filter(0.1748, 0.0, 0.062921, 0.292119) {}
};
struct agg_stack_blur : image_filter_base
{
agg_stack_blur()
@ -98,6 +103,7 @@ struct agg_stack_blur : image_filter_base
struct color_to_alpha : image_filter_base
{
color_to_alpha() {}
color_to_alpha(mapnik::color const& c)
: color(c) {}
inline bool operator==(color_to_alpha const& rhs) const
@ -109,6 +115,7 @@ struct color_to_alpha : image_filter_base
struct scale_hsla : image_filter_base
{
scale_hsla() {}
scale_hsla(double _h0, double _h1,
double _s0, double _s1,
double _l0, double _l1,

View file

@ -153,8 +153,9 @@ source = Split(
request.cpp
well_known_srs.cpp
params.cpp
image_filter_types.cpp
image_filter_grammar.cpp
parse_image_filters.cpp
generate_image_filters.cpp
image_filter_grammar_x3.cpp
color.cpp
conversions.cpp
image_copy.cpp
@ -219,7 +220,6 @@ source = Split(
svg/svg_points_parser.cpp
svg/svg_transform_parser.cpp
warp.cpp
css_color_grammar.cpp
css_color_grammar_x3.cpp
vertex_cache.cpp
text/font_library.cpp

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
* Copyright (C) 2016 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -19,9 +19,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
// mapnik
#include <mapnik/image_filter_types.hpp>
#include <mapnik/image_filter_grammar.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
@ -43,18 +43,4 @@ bool generate_image_filters(std::back_insert_iterator<std::string> & sink, std::
return r;
}
bool parse_image_filters(std::string const& filters, std::vector<filter_type>& image_filters)
{
std::string::const_iterator itr = filters.begin();
std::string::const_iterator end = filters.end();
static const mapnik::image_filter_grammar<std::string::const_iterator,
std::vector<mapnik::filter::filter_type> > filter_grammar;
boost::spirit::qi::ascii::space_type space;
bool r = boost::spirit::qi::phrase_parse(itr,end,
filter_grammar,
space,
image_filters);
return r && itr==end;
}
}}

View file

@ -20,10 +20,14 @@
*
*****************************************************************************/
#include <mapnik/image_filter_grammar.hpp>
#include <mapnik/image_filter_grammar_impl.hpp>
#include <mapnik/image_filter_types.hpp>
#include <string>
#include <vector>
#include <mapnik/image_filter_grammar_x3_def.hpp>
template struct mapnik::image_filter_grammar<std::string::const_iterator,std::vector<mapnik::filter::filter_type>>;
namespace mapnik { namespace image_filter {
namespace x3 = boost::spirit::x3;
using iterator_type = std::string::const_iterator;
using context_type = x3::phrase_parse_context<x3::ascii::space_type>::type;
BOOST_SPIRIT_INSTANTIATE(image_filter_grammar_type, iterator_type, context_type);
}} // image_filter //mapnik

View file

@ -20,12 +20,35 @@
*
*****************************************************************************/
// NOTE: we define this here in a cpp because def is needed twice:
// once by src/color_factory.cpp and once by include/mapnik/image_filter_grammar.hpp
// otherwise it would make sense to simply do `#include <mapnik/css_color_grammar_impl.hpp>`
// in a single file
#include <mapnik/color.hpp>
#include <mapnik/css_color_grammar_impl.hpp>
#include <string>
// mapnik
#include <mapnik/image_filter_types.hpp>
#include <mapnik/image_filter_grammar_x3.hpp>
// stl
#include <vector>
template struct mapnik::css_color_grammar<std::string::const_iterator>;
namespace mapnik {
namespace filter {
bool parse_image_filters(std::string const& str, std::vector<filter_type> & image_filters)
{
using namespace boost::spirit::x3::ascii;
auto const& grammar = mapnik::image_filter_grammar();
auto itr = str.begin();
auto end = str.end();
boost::spirit::x3::ascii::space_type space;
bool r = false;
try
{
r = boost::spirit::x3::phrase_parse(itr, end, grammar, space, image_filters);
}
catch (...)
{
image_filters.clear();
r = false;
}
return r && itr==end;
}
}}