-
-
Save jc101/f318c4bceb8a6c5f6d6e to your computer and use it in GitHub Desktop.
Basic text and point support for Mapnik (branch 1d981e899bed8103740a59c48954621cda7f3f36)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/include/mapnik/color.hpp b/include/mapnik/color.hpp | |
index 690803a..06d4302 100644 | |
--- a/include/mapnik/color.hpp | |
+++ b/include/mapnik/color.hpp | |
@@ -91,6 +91,7 @@ public: | |
std::string to_string() const; | |
std::string to_hex_string() const; | |
+ std::string to_hex_string_no_alpha() const; | |
bool premultiply(); | |
bool demultiply(); | |
diff --git a/include/mapnik/marker_cache.hpp b/include/mapnik/marker_cache.hpp | |
index 47aa555..355919d 100644 | |
--- a/include/mapnik/marker_cache.hpp | |
+++ b/include/mapnik/marker_cache.hpp | |
@@ -56,6 +56,7 @@ public: | |
bool is_svg_uri(std::string const& path); | |
bool is_image_uri(std::string const& path); | |
std::shared_ptr<marker const> find(std::string const& key, bool update_cache = false); | |
+ bool contains_marker(std::string const& uri); | |
void clear(); | |
}; | |
diff --git a/include/mapnik/svg/output/svg_generator.hpp b/include/mapnik/svg/output/svg_generator.hpp | |
index 1b3f18d..1863c6d 100644 | |
--- a/include/mapnik/svg/output/svg_generator.hpp | |
+++ b/include/mapnik/svg/output/svg_generator.hpp | |
@@ -55,7 +55,7 @@ namespace mapnik { namespace svg { | |
void generate_opening_group(mapnik::value_integer val); | |
void generate_opening_group(std::string const& val); | |
void generate_closing_group(); | |
- OutputIterator& output_iterator_; | |
+ OutputIterator& output_iterator_; | |
}; | |
}} | |
diff --git a/include/mapnik/svg/output/svg_output_attributes.hpp b/include/mapnik/svg/output/svg_output_attributes.hpp | |
index 00deeea..cbc770e 100644 | |
--- a/include/mapnik/svg/output/svg_output_attributes.hpp | |
+++ b/include/mapnik/svg/output/svg_output_attributes.hpp | |
@@ -31,6 +31,9 @@ | |
// stl | |
#include <string> | |
+// boost | |
+#include <boost/optional.hpp> | |
+ | |
namespace mapnik { namespace svg { | |
/*! | |
@@ -66,8 +69,9 @@ namespace mapnik { namespace svg { | |
void set_stroke_width(double stroke_width); | |
void set_stroke_linecap(line_cap_e stroke_linecap); | |
void set_stroke_linejoin(line_join_e stroke_linejoin); | |
- void set_stroke_dasharray(dash_array const& stroke_dasharray); | |
+ void set_stroke_dasharray(boost::optional<dash_array> stroke_dasharray); | |
void set_stroke_dashoffset(double stroke_dashoffset); | |
+ void set_path_id(std::string id); | |
std::string const& fill_color() const; | |
double fill_opacity() const; | |
@@ -76,8 +80,9 @@ namespace mapnik { namespace svg { | |
double stroke_width() const; | |
std::string const& stroke_linecap() const; | |
std::string const& stroke_linejoin() const; | |
- dash_array const& stroke_dasharray() const; | |
+ boost::optional<dash_array> stroke_dasharray() const; | |
double stroke_dashoffset() const; | |
+ std::string const& path_id() const; | |
/*! | |
* @brief Set members back to their default values. | |
@@ -95,8 +100,9 @@ namespace mapnik { namespace svg { | |
double stroke_width_; | |
std::string stroke_linecap_; | |
std::string stroke_linejoin_; | |
- dash_array stroke_dasharray_; | |
+ boost::optional<dash_array> stroke_dasharray_; | |
double stroke_dashoffset_; | |
+ std::string path_id_; | |
}; | |
/*! | |
@@ -118,7 +124,7 @@ namespace mapnik { namespace svg { | |
y_(0), | |
width_(400), | |
height_(400), | |
- fill_color_("#000000") | |
+ fill_color_("#00000000") | |
{} | |
rect_output_attributes(const int x, const int y, const unsigned width, const unsigned height, color const& fill_color) | |
@@ -197,6 +203,218 @@ namespace mapnik { namespace svg { | |
double svg_version_; | |
std::string svg_namespace_url_; | |
}; | |
+ | |
+ | |
+ /*! | |
+ * \brief The text_output_attributes struct | |
+ * This structure encapsulates the values needed to | |
+ * generate an svg (root) tag. | |
+ * | |
+ * The values are stored using the variable types that | |
+ * are required for output generation, but the interface | |
+ * is written with the original types. "set" methods | |
+ * perform the necessary conversions (i.e. from color to | |
+ * hex string | |
+ */ | |
+ struct text_output_attributes | |
+ { | |
+ text_output_attributes() | |
+ : text_ratio_(0), | |
+ text_size_(10), | |
+ char_spacing_(0), | |
+ transform_("none") | |
+ {;} | |
+ | |
+ // general layout options | |
+ void set_text_ratio(const double ratio); | |
+ // character formatting options | |
+ void set_face_name(const std::string &name); | |
+ void set_fontset(const std::string &name); | |
+ void set_text_size(const double size); | |
+ void set_char_spacing(const double &space); | |
+ void set_text_transform(const text_transform_e &trans); | |
+ | |
+ double text_ratio() const; | |
+ std::string face_name() const; | |
+ std::string fontset() const; | |
+ double text_size() const; | |
+ double halo_radius() const; | |
+ double char_spacing() const; | |
+ std::string transform() const; | |
+ | |
+ // reset to default values | |
+ void reset(); | |
+ | |
+ // general layout options | |
+ // - text-ratio | |
+ // character formatting options | |
+ // - face-name | |
+ // - fontset-name | |
+ // - size | |
+ // - character spacing | |
+ // - text-transform | |
+ double text_ratio_; | |
+ std::string face_name_; | |
+ std::string fontset_; | |
+ double text_size_; | |
+ double char_spacing_; | |
+ std::string transform_; | |
+ }; | |
+ | |
+ struct text_output_attributes_stroke : public text_output_attributes { | |
+ text_output_attributes_stroke() | |
+ : text_output_attributes(), | |
+ halo_fill_("#FFFFFF"), | |
+ stroke_opacity_(1.0), | |
+ halo_radius_(0) | |
+ {;} | |
+ | |
+ // character formatting options | |
+ void set_halo_fill(const color &fill); | |
+ void set_halo_radius(const double &radius); | |
+ | |
+ std::string halo_fill() const; | |
+ double stroke_opacity() const; | |
+ double halo_radius() const; | |
+ | |
+ // reset to default values | |
+ void reset(); | |
+ | |
+ // character formatting options | |
+ // - hallo-fill | |
+ // - halo-radius | |
+ std::string halo_fill_; | |
+ double stroke_opacity_; | |
+ double halo_radius_; | |
+ }; | |
+ | |
+ /*! | |
+ * \brief The text_output_attributes struct | |
+ * This structure encapsulates the values needed to | |
+ * generate an svg (root) tag. | |
+ * | |
+ * The values are stored using the variable types that | |
+ * are required for output generation, but the interface | |
+ * is written with the original types. "set" methods | |
+ * perform the necessary conversions (i.e. from color to | |
+ * hex string | |
+ */ | |
+ struct text_output_attributes_fill : public text_output_attributes | |
+ { | |
+ text_output_attributes_fill() | |
+ : text_output_attributes(), | |
+ fill_("#000000"), | |
+ fill_opacity_(1.0) | |
+ {;} | |
+ | |
+ // character formatting options | |
+ void set_fill(const color &fill); | |
+ | |
+ std::string fill() const; | |
+ double fill_opacity() const; | |
+ | |
+ // reset to default values | |
+ void reset(); | |
+ | |
+ // character formatting options | |
+ // - fill | |
+ std::string fill_; | |
+ double fill_opacity_; | |
+ }; | |
+ | |
+ /*! | |
+ * @brief SVG image tag attributes. | |
+ * This structure encapsulates the values needed to | |
+ * generate an image tag. It is is meant to be used to | |
+ * store the underlying image for eg point symbolizers. | |
+ */ | |
+ struct image_output_attributes | |
+ { | |
+ image_output_attributes() | |
+ : id_(), | |
+ href_(), | |
+ x_(0.0), | |
+ y_(0.0), | |
+ width_(16.0), | |
+ height_(16.0) | |
+ {} | |
+ | |
+ image_output_attributes(const std::string id, const std::string href, double x, const double y, const double width, const double height) | |
+ : id_(id), | |
+ href_(href), | |
+ x_(x), | |
+ y_(y), | |
+ width_(width), | |
+ height_(height) | |
+ {} | |
+ | |
+ void set_x(const double x); | |
+ void set_y(const double y); | |
+ void set_width(const double width); | |
+ void set_height(const double height); | |
+ void set_href(std::string const& href); | |
+ void set_id(std::string const& id); | |
+ | |
+ double x() const; | |
+ double y() const; | |
+ double width() const; | |
+ double height() const; | |
+ std::string const& href() const; | |
+ std::string const& id() const; | |
+ | |
+ /*! | |
+ * @brief Set members back to their default values. | |
+ */ | |
+ void reset(); | |
+ | |
+ //private: | |
+ double x_; | |
+ double y_; | |
+ double width_; | |
+ double height_; | |
+ std::string href_; | |
+ std::string id_; | |
+ }; | |
+ | |
+ /*! | |
+ * @brief SVG image tag attributes. | |
+ * This structure encapsulates the values needed to | |
+ * generate an image tag. It is is meant to be used to | |
+ * store the underlying image for eg use symbolizers. | |
+ */ | |
+ struct use_output_attributes | |
+ { | |
+ use_output_attributes() | |
+ : x_(0.0), | |
+ y_(0.0), | |
+ href_() | |
+ {} | |
+ | |
+ use_output_attributes(const double x, const double y, const std::string href) | |
+ : x_(x), | |
+ y_(y), | |
+ href_(href) | |
+ {} | |
+ | |
+ void set_x(const double x); | |
+ void set_y(const double y); | |
+ void set_href(std::string const& href); | |
+ | |
+ double x() const; | |
+ double y() const; | |
+ std::string const& href() const; | |
+ | |
+ /*! | |
+ * @brief Set members back to their default values. | |
+ */ | |
+ void reset(); | |
+ | |
+ //private: | |
+ double x_; | |
+ double y_; | |
+ std::string href_; | |
+ }; | |
+ | |
}} | |
#endif // MAPNIK_SVG_OUTPUT_ATTRIBUTES | |
diff --git a/include/mapnik/svg/output/svg_output_grammars.hpp b/include/mapnik/svg/output/svg_output_grammars.hpp | |
index 769671b..0448af9 100644 | |
--- a/include/mapnik/svg/output/svg_output_grammars.hpp | |
+++ b/include/mapnik/svg/output/svg_output_grammars.hpp | |
@@ -34,6 +34,9 @@ namespace mapnik { namespace svg { | |
struct path_output_attributes; | |
struct rect_output_attributes; | |
struct root_output_attributes; | |
+ struct text_output_attributes; | |
+ struct text_output_attributes_fill; | |
+ struct text_output_attributes_stroke; | |
}} | |
#pragma GCC diagnostic push | |
@@ -60,6 +63,7 @@ BOOST_FUSION_ADAPT_STRUCT( | |
(std::string, stroke_linecap_) | |
(std::string, stroke_linejoin_) | |
(double, stroke_dashoffset_) | |
+ (std::string, path_id_) | |
); | |
/*! | |
@@ -83,10 +87,75 @@ BOOST_FUSION_ADAPT_STRUCT( | |
mapnik::svg::root_output_attributes, | |
(unsigned, width_) | |
(unsigned, height_) | |
- (double, svg_version_) | |
+ (unsigned, width_) | |
+ (unsigned, height_) | |
+ (double, svg_version_) | |
(std::string, svg_namespace_url_) | |
); | |
+/*! | |
+ * mapnik::svg::text_output_attributes is adapted as a fusion sequence | |
+ * in order to be used directly by the text_output_attributes (below). | |
+ */ | |
+BOOST_FUSION_ADAPT_STRUCT( | |
+ mapnik::svg::text_output_attributes, | |
+ (std::string, face_name_) | |
+ (double, text_size_) | |
+ (std::string, transform_) | |
+ ); | |
+ | |
+/*! | |
+ * mapnik::svg::text_output_attributes is adapted as a fusion sequence | |
+ * in order to be used directly by the text_output_attributes (below). | |
+ */ | |
+BOOST_FUSION_ADAPT_STRUCT( | |
+ mapnik::svg::text_output_attributes_fill, | |
+ (std::string, face_name_) | |
+ (double, text_size_) | |
+ (std::string, transform_) | |
+ (std::string, fill_) | |
+ (double, fill_opacity_) | |
+ ); | |
+ | |
+/*! | |
+ * mapnik::svg::text_output_attributes is adapted as a fusion sequence | |
+ * in order to be used directly by the text_output_attributes (below). | |
+ */ | |
+BOOST_FUSION_ADAPT_STRUCT( | |
+ mapnik::svg::text_output_attributes_stroke, | |
+ (std::string, face_name_) | |
+ (double, text_size_) | |
+ (std::string, transform_) | |
+ (std::string, halo_fill_) | |
+ (double, stroke_opacity_) | |
+ (double, halo_radius_) | |
+ ); | |
+ | |
+/*! | |
+* mapnik::svg::text_output_attributes is adapted as a fusion sequence | |
+* in order to be used directly by the text_output_attributes (below). | |
+*/ | |
+BOOST_FUSION_ADAPT_STRUCT( | |
+ mapnik::svg::image_output_attributes, | |
+ (std::string, id_) | |
+ (std::string, href_) | |
+ (double, x_) | |
+ (double, y_) | |
+ (double, width_) | |
+ (double, height_) | |
+ ); | |
+ | |
+/*! | |
+* mapnik::svg::text_output_attributes is adapted as a fusion sequence | |
+* in order to be used directly by the text_output_attributes (below). | |
+*/ | |
+BOOST_FUSION_ADAPT_STRUCT( | |
+ mapnik::svg::use_output_attributes, | |
+ (std::string, href_) | |
+ (double, x_) | |
+ (double, y_) | |
+ ); | |
+ | |
namespace mapnik { namespace svg { | |
using namespace boost::spirit; | |
@@ -119,7 +188,42 @@ struct svg_root_attributes_grammar : karma::grammar<OutputIterator, mapnik::svg: | |
explicit svg_root_attributes_grammar(); | |
karma::rule<OutputIterator, mapnik::svg::root_output_attributes()> svg_root_attributes; | |
}; | |
-} | |
-} | |
+ | |
+template <typename OutputIterator> | |
+struct svg_text_attributes_grammar : karma::grammar<OutputIterator, mapnik::svg::text_output_attributes()> | |
+{ | |
+ explicit svg_text_attributes_grammar(); | |
+ karma::rule<OutputIterator, mapnik::svg::text_output_attributes()> svg_text_attributes; | |
+}; | |
+ | |
+template <typename OutputIterator> | |
+struct svg_text_fill_attributes_grammar : karma::grammar<OutputIterator, mapnik::svg::text_output_attributes_fill()> | |
+{ | |
+ explicit svg_text_fill_attributes_grammar(); | |
+ karma::rule<OutputIterator, mapnik::svg::text_output_attributes_fill()> svg_text_attributes_fill; | |
+}; | |
+ | |
+template <typename OutputIterator> | |
+struct svg_text_stroke_attributes_grammar : karma::grammar<OutputIterator, mapnik::svg::text_output_attributes_stroke()> | |
+{ | |
+ explicit svg_text_stroke_attributes_grammar(); | |
+ karma::rule<OutputIterator, mapnik::svg::text_output_attributes_stroke()> svg_text_attributes_stroke; | |
+}; | |
+ | |
+template <typename OutputIterator> | |
+struct svg_image_attributes_grammar : karma::grammar<OutputIterator, mapnik::svg::image_output_attributes()> | |
+{ | |
+ explicit svg_image_attributes_grammar(); | |
+ karma::rule<OutputIterator, mapnik::svg::image_output_attributes()> svg_image_attributes; | |
+}; | |
+ | |
+template <typename OutputIterator> | |
+struct svg_use_attributes_grammar : karma::grammar<OutputIterator, mapnik::svg::use_output_attributes()> | |
+{ | |
+ explicit svg_use_attributes_grammar(); | |
+ karma::rule<OutputIterator, mapnik::svg::use_output_attributes()> svg_use_attributes; | |
+}; | |
+ | |
+}} | |
#endif // SVG_OUTPUT_GRAMMARS_HPP | |
diff --git a/include/mapnik/svg/output/svg_output_grammars_impl.hpp b/include/mapnik/svg/output/svg_output_grammars_impl.hpp | |
index cbce919..007e0a3 100644 | |
--- a/include/mapnik/svg/output/svg_output_grammars_impl.hpp | |
+++ b/include/mapnik/svg/output/svg_output_grammars_impl.hpp | |
@@ -45,15 +45,14 @@ svg_path_attributes_grammar<OutputIterator>::svg_path_attributes_grammar() | |
karma::string_type kstring; | |
svg_path_attributes = | |
- lit("fill=\"") | |
- << kstring | |
- << lit("\" fill-opacity=\"") << double_ | |
- << lit("\" stroke=\"") << kstring | |
- << lit("\" stroke-opacity=\"") << double_ | |
- << lit("\" stroke-width=\"") << double_ << lit("px") | |
- << lit("\" stroke-linecap=\"") << kstring | |
- << lit("\" stroke-linejoin=\"") << kstring | |
- << lit("\" stroke-dashoffset=\"") << double_ << lit("px") << lit('"'); | |
+ lit("fill=\"") << kstring << lit("\" ") | |
+ << lit("fill-opacity=\"") << double_ << lit("\" ") | |
+ << lit("stroke=\"") << kstring << lit("\" ") | |
+ << lit("stroke-opacity=\"") << double_ << lit("\" ") | |
+ << lit("stroke-width=\"") << double_ << lit("\" ") | |
+ << lit("stroke-linecap=\"") << kstring << lit("\" ") | |
+ << lit("stroke-linejoin=\"") << kstring << lit("\" ") | |
+ << lit("stroke-dashoffset=\"") << double_ << lit("\""); | |
} | |
template <typename OutputIterator> | |
@@ -76,12 +75,11 @@ svg_rect_attributes_grammar<OutputIterator>::svg_rect_attributes_grammar() | |
karma::string_type kstring; | |
svg_rect_attributes = | |
- lit("x=\"") | |
- << int_ | |
- << lit("\" y=\"") << int_ | |
- << lit("\" width=\"") << int_ << lit("px") | |
- << lit("\" height=\"") << int_ << lit("px") | |
- << lit("\" fill=\"") << kstring << lit('"'); | |
+ lit("x=\"") << int_ << lit("\" ") | |
+ << lit("y=\"") << int_ << lit("\" ") | |
+ << lit("width=\"") << int_ << lit("\" ") | |
+ << lit("height=\"") << int_ << lit("\" ") | |
+ << lit("fill=\"") << kstring << lit("\""); | |
} | |
template <typename OutputIterator> | |
@@ -94,14 +92,107 @@ svg_root_attributes_grammar<OutputIterator>::svg_root_attributes_grammar() | |
karma::double_type double_; | |
svg_root_attributes = | |
- lit("width=\"") | |
- << int_ | |
- << lit("px") | |
- << lit("\" height=\"") << int_ << lit("px") | |
- << lit("\" version=\"") << double_ | |
- << lit("\" xmlns=\"") << kstring | |
- << lit("\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\""); | |
+ lit("width=\"") << int_ << lit("\" ") | |
+ << lit("height=\"") << int_ << lit("\" ") | |
+ << lit("viewBox=\"0 0 ") << int_ << lit(" ") << int_ << lit("\" ") | |
+ << lit("version=\"") << double_ << lit("\" ") | |
+ << lit("xmlns=\"") << kstring << lit("\" ") | |
+ << lit("xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" ") | |
+ << lit("xmlns:xlink=\"http://www.w3.org/1999/xlink\""); | |
} | |
+template <typename OutputIterator> | |
+svg_text_attributes_grammar<OutputIterator>::svg_text_attributes_grammar() | |
+ : svg_text_attributes_grammar::base_type(svg_text_attributes) | |
+{ | |
+ karma::lit_type lit; | |
+ karma::string_type kstring; | |
+ karma::double_type double_; | |
+ | |
+ svg_text_attributes = | |
+ lit(" font-family=\"") << kstring << lit("\" ") | |
+ << lit("font-size=\"") << double_ << lit("\" ") | |
+ // << lit(" fill=") << kstring | |
+ // << lit(" fill-opacity=") << double_ | |
+ // << lit(" style=\"") | |
+ // << lit("stroke: ") << kstring | |
+ // << lit("; stroke-opacity: ") << double_ | |
+ // << "; stroke-width: " << double_ | |
+ // << lit("\"") | |
+ << lit("text-transform=\"") << kstring << lit("\" "); | |
+ | |
+} | |
+ | |
+template <typename OutputIterator> | |
+svg_text_fill_attributes_grammar<OutputIterator>::svg_text_fill_attributes_grammar() | |
+ : svg_text_fill_attributes_grammar::base_type(svg_text_attributes_fill) | |
+{ | |
+ karma::lit_type lit; | |
+ karma::string_type kstring; | |
+ karma::double_type double_; | |
+ | |
+ svg_text_attributes_fill = | |
+ lit(" font-family=\"") << kstring << lit("\" ") | |
+ << lit(" font-size=\"") << double_ << lit("\" ") | |
+ << lit(" text-transform=\"") << kstring << lit("\" ") | |
+ << lit(" fill=\"") << kstring << lit("\" ") | |
+ << lit(" fill-opacity=\"") << double_ << lit("\" "); | |
+ | |
+ | |
+} | |
+ | |
+template <typename OutputIterator> | |
+svg_text_stroke_attributes_grammar<OutputIterator>::svg_text_stroke_attributes_grammar() | |
+ : svg_text_stroke_attributes_grammar::base_type(svg_text_attributes_stroke) | |
+{ | |
+ karma::lit_type lit; | |
+ karma::string_type kstring; | |
+ karma::double_type double_; | |
+ | |
+ svg_text_attributes_stroke = | |
+ lit(" font-family=\"") << kstring << lit("\" ") | |
+ << lit("font-size=\"") << double_ << lit("\" ") | |
+ << lit("text-transform=\"") << kstring << lit("\" ") | |
+ << lit("fill=\"none\" ") | |
+ << lit("style=\"") | |
+ << lit("stroke: ") << kstring << lit("; ") | |
+ << lit("stroke-opacity: ") << double_ << lit("; ") | |
+ << "stroke-width: " << double_ | |
+ << lit("\""); | |
+ | |
+} | |
+ | |
+template <typename OutputIterator> | |
+svg_image_attributes_grammar<OutputIterator>::svg_image_attributes_grammar() | |
+ : svg_image_attributes_grammar::base_type(svg_image_attributes) | |
+{ | |
+ karma::lit_type lit; | |
+ karma::string_type kstring; | |
+ karma::double_type double_; | |
+ | |
+ svg_image_attributes = | |
+ lit(" id=\"") << kstring << lit("\" ") | |
+ << lit("xlink:href=\"") << kstring << lit("\" ") | |
+ << lit("x=\"") << double_ << lit("\" ") | |
+ << lit("y=\"") << double_ << lit("\" ") | |
+ << lit("width=\"") << double_ << lit("\" ") | |
+ << lit("height=\"") << double_ << lit("\" "); | |
+ | |
} | |
+ | |
+template <typename OutputIterator> | |
+svg_use_attributes_grammar<OutputIterator>::svg_use_attributes_grammar() | |
+ : svg_use_attributes_grammar::base_type(svg_use_attributes) | |
+{ | |
+ karma::lit_type lit; | |
+ karma::string_type kstring; | |
+ karma::double_type double_; | |
+ | |
+ svg_use_attributes = | |
+ lit(" xlink:href=\"#") << kstring << lit("\" ") | |
+ << lit("x=\"") << double_ << lit("\" ") | |
+ << lit("y=\"") << double_ << lit("\" "); | |
+ | |
} | |
+ | |
+}} | |
diff --git a/include/mapnik/svg/output/svg_renderer.hpp b/include/mapnik/svg/output/svg_renderer.hpp | |
index 037ec0d..ac465af 100644 | |
--- a/include/mapnik/svg/output/svg_renderer.hpp | |
+++ b/include/mapnik/svg/output/svg_renderer.hpp | |
@@ -88,11 +88,14 @@ public: | |
void process(polygon_symbolizer const& sym, | |
mapnik::feature_impl & feature, | |
proj_transform const& prj_trans); | |
- // unimplemented | |
- void process(point_symbolizer const&, | |
- mapnik::feature_impl &, | |
- proj_transform const&) {} | |
- void process(line_pattern_symbolizer const&, | |
+ void process(text_symbolizer const&, | |
+ mapnik::feature_impl &, | |
+ proj_transform const& prj_trans); | |
+ void process(point_symbolizer const& sym, | |
+ mapnik::feature_impl & feature, | |
+ proj_transform const& prj_trans); | |
+ // unimplemented | |
+ void process(line_pattern_symbolizer const&, | |
mapnik::feature_impl &, | |
proj_transform const&) {} | |
void process(polygon_pattern_symbolizer const&, | |
@@ -104,9 +107,6 @@ public: | |
void process(shield_symbolizer const&, | |
mapnik::feature_impl &, | |
proj_transform const&) {} | |
- void process(text_symbolizer const&, | |
- mapnik::feature_impl &, | |
- proj_transform const&) {} | |
void process(building_symbolizer const&, | |
mapnik::feature_impl &, | |
proj_transform const&) {} | |
diff --git a/include/mapnik/text/glyph_info.hpp b/include/mapnik/text/glyph_info.hpp | |
index 3950f9d..c3e3cda 100644 | |
--- a/include/mapnik/text/glyph_info.hpp | |
+++ b/include/mapnik/text/glyph_info.hpp | |
@@ -26,6 +26,7 @@ | |
#include <mapnik/text/evaluated_format_properties_ptr.hpp> | |
#include <mapnik/pixel_position.hpp> | |
#include <mapnik/util/noncopyable.hpp> | |
+#include <mapnik/value.hpp> | |
#include <memory> | |
#include <cmath> | |
@@ -50,7 +51,8 @@ struct glyph_info : util::noncopyable | |
unscaled_advance(0.0), | |
unscaled_line_height(0.0), | |
scale_multiplier(1.0), | |
- offset() {} | |
+ offset(), | |
+ string_value(0) {} | |
glyph_info(glyph_info && rhs) | |
: glyph_index(std::move(rhs.glyph_index)), | |
char_index(std::move(rhs.char_index)), | |
@@ -61,7 +63,8 @@ struct glyph_info : util::noncopyable | |
unscaled_advance(std::move(rhs.unscaled_advance)), | |
unscaled_line_height(std::move(rhs.unscaled_line_height)), | |
scale_multiplier(std::move(rhs.scale_multiplier)), | |
- offset(std::move(rhs.offset)) {} | |
+ offset(std::move(rhs.offset)), | |
+ string_value(rhs.string_value) {} | |
unsigned glyph_index; | |
// Position in the string of all characters i.e. before itemizing | |
@@ -74,8 +77,9 @@ struct glyph_info : util::noncopyable | |
// Line height returned by freetype, includes normal font | |
// line spacing, but not additional user defined spacing | |
double unscaled_line_height; | |
+ std::shared_ptr<value_unicode_string> string_value; | |
double scale_multiplier; | |
- pixel_position offset; | |
+ pixel_position offset; | |
double ymin() const { return unscaled_ymin * 64.0 * scale_multiplier; } | |
double ymax() const { return unscaled_ymax * 64.0 * scale_multiplier; } | |
diff --git a/include/mapnik/text/harfbuzz_shaper.hpp b/include/mapnik/text/harfbuzz_shaper.hpp | |
index 0f23bc8..87b83df 100644 | |
--- a/include/mapnik/text/harfbuzz_shaper.hpp | |
+++ b/include/mapnik/text/harfbuzz_shaper.hpp | |
@@ -153,7 +153,10 @@ static void shape_text(text_line & line, | |
continue; | |
} | |
- double max_glyph_height = 0; | |
+ | |
+ std::shared_ptr<value_unicode_string> curr_string(new value_unicode_string()); | |
+ text.extract(text_item.start, text_item.end - text_item.start, *curr_string.get()); | |
+ double max_glyph_height = 0; | |
for (unsigned i=0; i<num_glyphs; ++i) | |
{ | |
auto& gpos = positions[i]; | |
@@ -167,7 +170,8 @@ static void shape_text(text_line & line, | |
} | |
unsigned char_index = glyph.cluster; | |
glyph_info g(glyph.codepoint,char_index,text_item.format_); | |
- if (theface->glyph_dimensions(g)) | |
+ g.string_value = curr_string; | |
+ if (theface->glyph_dimensions(g)) | |
{ | |
g.face = theface; | |
g.scale_multiplier = size / theface->get_face()->units_per_EM; | |
@@ -177,7 +181,7 @@ static void shape_text(text_line & line, | |
double tmp_height = g.height(); | |
if (tmp_height > max_glyph_height) max_glyph_height = tmp_height; | |
width_map[char_index] += g.advance(); | |
- line.add_glyph(std::move(g), scale_factor); | |
+ line.add_glyph(std::move(g), scale_factor); | |
} | |
} | |
line.update_max_char_height(max_glyph_height); | |
diff --git a/include/mapnik/text/icu_shaper.hpp b/include/mapnik/text/icu_shaper.hpp | |
index bcd822b..950aea1 100644 | |
--- a/include/mapnik/text/icu_shaper.hpp | |
+++ b/include/mapnik/text/icu_shaper.hpp | |
@@ -90,12 +90,18 @@ static void shape_text(text_line & line, | |
std::size_t num_chars = static_cast<std::size_t>(num_char); | |
shaped.releaseBuffer(length); | |
bool shaped_status = true; | |
+ | |
+ | |
double max_glyph_height = 0; | |
if (U_SUCCESS(err) && (num_chars == length)) | |
{ | |
unsigned char_index = 0; | |
U_NAMESPACE_QUALIFIER StringCharacterIterator iter(shaped); | |
- for (iter.setToStart(); iter.hasNext();) | |
+ | |
+ std::shared_ptr<value_unicode_string> curr_string(new value_unicode_string()); | |
+ text.extract(text_item.start, text_item.end - text_item.start, *curr_string.get()); | |
+ | |
+ for (iter.setToStart(); iter.hasNext();) | |
{ | |
UChar ch = iter.nextPostInc(); | |
auto codepoint = FT_Get_Char_Index(face->get_face(), ch); | |
@@ -110,11 +116,13 @@ static void shape_text(text_line & line, | |
{ | |
g.face = face; | |
g.scale_multiplier = size / face->get_face()->units_per_EM; | |
+ g.string_value = curr_string; | |
double tmp_height = g.height(); | |
if (tmp_height > max_glyph_height) max_glyph_height = tmp_height; | |
width_map[char_index++] += g.advance(); | |
line.add_glyph(std::move(g), scale_factor); | |
} | |
+ | |
} | |
} | |
if (!shaped_status) continue; | |
diff --git a/include/mapnik/value_types.hpp b/include/mapnik/value_types.hpp | |
index 85a015b..92328d2 100644 | |
--- a/include/mapnik/value_types.hpp | |
+++ b/include/mapnik/value_types.hpp | |
@@ -27,6 +27,11 @@ | |
#include <mapnik/config.hpp> | |
#include <mapnik/pixel_types.hpp> | |
+//#ifndef BOOST_SPIRIT_UNICODE | |
+//#define BOOST_SPIRIT_UNICODE | |
+//#endif | |
+ | |
+ | |
// icu | |
#include <unicode/uversion.h> // for U_NAMESPACE_QUALIFIER | |
diff --git a/src/build.py b/src/build.py | |
index c405eb1..032cf85 100644 | |
--- a/src/build.py | |
+++ b/src/build.py | |
@@ -383,6 +383,8 @@ if env['SVG_RENDERER']: # svg backend | |
svg/output/process_symbolizers.cpp | |
svg/output/process_line_symbolizer.cpp | |
svg/output/process_polygon_symbolizer.cpp | |
+ svg/output/process_text_symbolizer.cpp | |
+ svg/output/process_point_symbolizer.cpp | |
""") | |
lib_env.Append(CPPDEFINES = '-DSVG_RENDERER') | |
libmapnik_defines.append('-DSVG_RENDERER') | |
diff --git a/src/color.cpp b/src/color.cpp | |
index 2dcbe76..9d75581 100644 | |
--- a/src/color.cpp | |
+++ b/src/color.cpp | |
@@ -1,41 +1,35 @@ | |
/***************************************************************************** | |
- * | |
- * 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 | |
- * | |
- *****************************************************************************/ | |
+* | |
+* 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/color.hpp> | |
#include <mapnik/color_factory.hpp> | |
#include <mapnik/config_error.hpp> | |
- | |
// agg | |
#include "agg_color_rgba.h" | |
#pragma GCC diagnostic push | |
#include <mapnik/warning_ignore.hpp> | |
#include <boost/spirit/include/karma.hpp> | |
-#include <boost/spirit/include/phoenix_statement.hpp> | |
-#include <boost/spirit/include/phoenix_core.hpp> | |
-#include <boost/spirit/include/phoenix_operator.hpp> | |
-#include <boost/spirit/include/phoenix_fusion.hpp> | |
-#include <boost/spirit/include/phoenix_function.hpp> | |
#pragma GCC diagnostic pop | |
// stl | |
@@ -43,79 +37,79 @@ | |
namespace mapnik { | |
-color::color(std::string const& str, bool premultiplied) | |
-{ | |
- *this = parse_color(str); | |
- premultiplied_ = premultiplied; | |
-} | |
+ color::color(std::string const& str, bool premultiplied) | |
+ { | |
+ *this = parse_color(str); | |
+ premultiplied_ = premultiplied; | |
+ } | |
-std::string color::to_string() const | |
-{ | |
- namespace karma = boost::spirit::karma; | |
- boost::spirit::karma::_1_type _1; | |
- boost::spirit::karma::eps_type eps; | |
- boost::spirit::karma::double_type double_; | |
- boost::spirit::karma::string_type kstring; | |
- boost::spirit::karma::uint_generator<uint8_t,10> color_generator; | |
- std::string str; | |
- std::back_insert_iterator<std::string> sink(str); | |
- karma::generate(sink, | |
- // begin grammar | |
- kstring[ boost::phoenix::if_(alpha()==255) [_1="rgb("].else_[_1="rgba("]] | |
- << color_generator[_1 = red()] << ',' | |
- << color_generator[_1 = green()] << ',' | |
- << color_generator[_1 = blue()] | |
- << kstring[ boost::phoenix::if_(alpha()==255) [_1 = ')'].else_[_1 =',']] | |
- << eps(alpha()<255) << double_ [_1 = alpha()/255.0] | |
- << ')' | |
- // end grammar | |
- ); | |
- return str; | |
-} | |
+ std::string color::to_string() const | |
+ { | |
+ namespace karma = boost::spirit::karma; | |
+ boost::spirit::karma::eps_type eps; | |
+ boost::spirit::karma::double_type double_; | |
+ boost::spirit::karma::uint_generator<uint8_t, 10> color_; | |
+ std::string str; | |
+ std::back_insert_iterator<std::string> sink(str); | |
+ karma::generate(sink, eps(alpha() < 255) | |
+ // begin grammar | |
+ << "rgba(" | |
+ << color_(red()) << ',' | |
+ << color_(green()) << ',' | |
+ << color_(blue()) << ',' | |
+ << double_(alpha() / 255.0) << ')' | |
+ | | |
+ "rgb(" | |
+ << color_(red()) << ',' | |
+ << color_(green()) << ',' | |
+ << color_(blue()) << ')' | |
+ // end grammar | |
+ ); | |
+ return str; | |
+ } | |
-std::string color::to_hex_string() const | |
-{ | |
- namespace karma = boost::spirit::karma; | |
- boost::spirit::karma::_1_type _1; | |
- boost::spirit::karma::hex_type hex; | |
- boost::spirit::karma::eps_type eps; | |
- boost::spirit::karma::right_align_type right_align; | |
- std::string str; | |
- std::back_insert_iterator<std::string> sink(str); | |
- karma::generate(sink, | |
- // begin grammar | |
- '#' | |
- << right_align(2,'0')[hex[_1 = red()]] | |
- << right_align(2,'0')[hex[_1 = green()]] | |
- << right_align(2,'0')[hex[_1 = blue()]] | |
- << eps(alpha() < 255) << right_align(2,'0')[hex [_1 = alpha()]] | |
- // end grammar | |
- ); | |
- return str; | |
-} | |
+ std::string color::to_hex_string() const | |
+ { | |
+ namespace karma = boost::spirit::karma; | |
+ boost::spirit::karma::hex_type hex; | |
+ boost::spirit::karma::eps_type eps; | |
+ boost::spirit::karma::right_align_type right_align; | |
+ std::string str; | |
+ std::back_insert_iterator<std::string> sink(str); | |
+ karma::generate(sink, | |
+ // begin grammar | |
+ '#' | |
+ << right_align(2, '0')[hex(red())] | |
+ << right_align(2, '0')[hex(green())] | |
+ << right_align(2, '0')[hex(blue())] | |
+ << eps(alpha() < 255) << right_align(2, '0')[hex(alpha())] | |
+ // end grammar | |
+ ); | |
+ return str; | |
+ } | |
-bool color::premultiply() | |
-{ | |
- if (premultiplied_) return false; | |
- agg::rgba8 pre_c = agg::rgba8(red_,green_,blue_,alpha_); | |
- pre_c.premultiply(); | |
- red_ = pre_c.r; | |
- green_ = pre_c.g; | |
- blue_ = pre_c.b; | |
- premultiplied_ = true; | |
- return true; | |
-} | |
+ bool color::premultiply() | |
+ { | |
+ if (premultiplied_) return false; | |
+ agg::rgba8 pre_c = agg::rgba8(red_, green_, blue_, alpha_); | |
+ pre_c.premultiply(); | |
+ red_ = pre_c.r; | |
+ green_ = pre_c.g; | |
+ blue_ = pre_c.b; | |
+ premultiplied_ = true; | |
+ return true; | |
+ } | |
-bool color::demultiply() | |
-{ | |
- if (!premultiplied_) return false; | |
- agg::rgba8 pre_c = agg::rgba8(red_,green_,blue_,alpha_); | |
- pre_c.demultiply(); | |
- red_ = pre_c.r; | |
- green_ = pre_c.g; | |
- blue_ = pre_c.b; | |
- premultiplied_ = false; | |
- return true; | |
-} | |
+ bool color::demultiply() | |
+ { | |
+ if (!premultiplied_) return false; | |
+ agg::rgba8 pre_c = agg::rgba8(red_, green_, blue_, alpha_); | |
+ pre_c.demultiply(); | |
+ red_ = pre_c.r; | |
+ green_ = pre_c.g; | |
+ blue_ = pre_c.b; | |
+ premultiplied_ = false; | |
+ return true; | |
+ } | |
-} | |
+} | |
\ No newline at end of file | |
diff --git a/src/marker_cache.cpp b/src/marker_cache.cpp | |
index 9e40622..411d405 100644 | |
--- a/src/marker_cache.cpp | |
+++ b/src/marker_cache.cpp | |
@@ -278,4 +278,13 @@ std::shared_ptr<mapnik::marker const> marker_cache::find(std::string const& uri, | |
return std::make_shared<mapnik::marker const>(mapnik::marker_null()); | |
} | |
+bool marker_cache::contains_marker(std::string const& uri) { | |
+ auto itr = marker_cache_.find(uri); | |
+ if (itr != marker_cache_.end()) | |
+ { | |
+ return true; | |
+ } | |
+ return false; | |
+} | |
+ | |
} | |
diff --git a/src/svg/output/process_line_symbolizer.cpp b/src/svg/output/process_line_symbolizer.cpp | |
index 5db205e..77eadeb 100644 | |
--- a/src/svg/output/process_line_symbolizer.cpp | |
+++ b/src/svg/output/process_line_symbolizer.cpp | |
@@ -34,16 +34,16 @@ namespace mapnik | |
*/ | |
template <typename T> | |
void svg_renderer<T>::process(line_symbolizer const& sym, | |
- mapnik::feature_impl & /*feature*/, | |
+ mapnik::feature_impl & feature, | |
proj_transform const& /*prj_trans*/) | |
{ | |
path_attributes_.set_stroke_color(get<color>(sym, keys::stroke, mapnik::color(0,0,0))); | |
path_attributes_.set_stroke_opacity(get<value_double>(sym,keys::stroke_opacity, 1.0)); | |
path_attributes_.set_stroke_width(get<value_double>(sym, keys::stroke_width, 1.0)); | |
- /* | |
- path_attributes_.set_stroke_linecap(sym.get_stroke().get_line_cap()); | |
- path_attributes_.set_stroke_linejoin(sym.get_stroke().get_line_join()); | |
- path_attributes_.set_stroke_dasharray(sym.get_stroke().get_dash_array()); | |
+ path_attributes_.set_stroke_linecap(get<line_cap_enum, keys::stroke_linecap>(sym, feature, common_.vars_)); | |
+ path_attributes_.set_stroke_linejoin(get<line_join_enum, keys::stroke_linejoin>(sym, feature, common_.vars_)); | |
+ path_attributes_.set_stroke_dasharray(get_optional<dash_array>(sym, keys::stroke_dasharray, feature, common_.vars_)); | |
+ /* | |
path_attributes_.set_stroke_dashoffset(sym.get_stroke().dash_offset()); | |
*/ | |
} | |
diff --git a/src/svg/output/process_point_symbolizer.cpp b/src/svg/output/process_point_symbolizer.cpp | |
index e69de29..bcca6ae 100644 | |
--- a/src/svg/output/process_point_symbolizer.cpp | |
+++ b/src/svg/output/process_point_symbolizer.cpp | |
@@ -0,0 +1,116 @@ | |
+/***************************************************************************** | |
+* | |
+* 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 | |
+* | |
+*****************************************************************************/ | |
+ | |
+#if defined(SVG_RENDERER) | |
+ | |
+// mapnik | |
+#include <mapnik/feature.hpp> | |
+#include <mapnik/svg/output/svg_renderer.hpp> | |
+#include <mapnik/image_util.hpp> | |
+#include <mapnik/image_any.hpp> | |
+#include <mapnik/geom_util.hpp> | |
+#include <mapnik/symbolizer.hpp> | |
+#include <mapnik/marker.hpp> | |
+#include <mapnik/marker_cache.hpp> | |
+#include <mapnik/parse_path.hpp> | |
+#include <mapnik/pixel_position.hpp> | |
+#include <mapnik/renderer_common/process_point_symbolizer.hpp> | |
+ | |
+#include <mapnik/svg/geometry_svg_generator_impl.hpp> | |
+#include <mapnik/svg/output/svg_output_attributes.hpp> | |
+#include <mapnik/svg/output/svg_output_grammars.hpp> | |
+ | |
+#include <mapnik/debug.hpp> | |
+ | |
+// stl | |
+#include <string> | |
+ | |
+// boost | |
+#include <boost/spirit/include/karma.hpp> | |
+ | |
+namespace mapnik { | |
+ | |
+ template <typename OutputIterator> | |
+ void generate_image_elem(OutputIterator & output_iterator, std::string id, std::string href, std::shared_ptr<marker const> m) { | |
+ svg::image_output_attributes image_attributes; | |
+ image_attributes.set_width(m->width()); | |
+ image_attributes.set_height(m->height()); | |
+ box2d<double> bbox = m->bounding_box(); | |
+ image_attributes.set_x(bbox.minx()); | |
+ image_attributes.set_y(bbox.miny()); | |
+ image_attributes.set_id(id); | |
+ image_attributes.set_href(href); | |
+ | |
+ static const svg::svg_image_attributes_grammar<OutputIterator> attributes_grammar; | |
+ boost::spirit::karma::lit_type lit; | |
+ boost::spirit::karma::generate(output_iterator, lit("<defs><image ") << attributes_grammar << lit("/></defs>\n"), image_attributes); | |
+ | |
+ } | |
+ | |
+ template <typename OutputIterator> | |
+ void render_marker(OutputIterator & output_iterator, pixel_position const& pos, marker const& marker, agg::trans_affine const& tr, double opacity, | |
+ composite_mode_e comp_op, std::string id) | |
+ { | |
+ svg::use_output_attributes use_attributes; | |
+ use_attributes.set_x(pos.x - (marker.width() * 0.5)); | |
+ use_attributes.set_y(pos.y - (marker.height() * 0.5)); | |
+ use_attributes.set_href(id); | |
+ | |
+ static const svg::svg_use_attributes_grammar<OutputIterator> attributes_grammar; | |
+ boost::spirit::karma::lit_type lit; | |
+ boost::spirit::karma::generate(output_iterator, lit("<use ") << attributes_grammar << lit("/>\n"), use_attributes); | |
+ } | |
+ | |
+ | |
+ template <typename T> | |
+ void svg_renderer<T>::process(point_symbolizer const& sym, | |
+ mapnik::feature_impl & feature, | |
+ proj_transform const& prj_trans) | |
+ { | |
+ composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over); | |
+ | |
+ std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_); | |
+ std::stringstream ss; | |
+ std::hash<std::string> hash_fn; | |
+ size_t hsh = hash_fn(filename); | |
+ ss << "png" << hsh; | |
+ std::string id = ss.str(); | |
+ | |
+ if (marker_cache::instance().contains_marker(filename)) { | |
+ generate_image_elem(generator_.output_iterator_, id, filename, marker_cache::instance().find(filename)); | |
+ } | |
+ | |
+ render_point_symbolizer( | |
+ sym, feature, prj_trans, common_, | |
+ [&](pixel_position const& pos, marker const& marker, | |
+ agg::trans_affine const& tr, double opacity) { | |
+ render_marker(generator_.output_iterator_, pos, marker, tr, opacity, comp_op, id); | |
+ }); | |
+ } | |
+ | |
+ | |
+ template void svg_renderer<std::ostream_iterator<char> >::process(point_symbolizer const&, | |
+ mapnik::feature_impl &, | |
+ proj_transform const&); | |
+} | |
+ | |
+#endif | |
\ No newline at end of file | |
diff --git a/src/svg/output/process_symbolizers.cpp b/src/svg/output/process_symbolizers.cpp | |
index 6ff486f..e637595 100644 | |
--- a/src/svg/output/process_symbolizers.cpp | |
+++ b/src/svg/output/process_symbolizers.cpp | |
@@ -85,6 +85,11 @@ struct symbol_type_dispatch | |
{ | |
return true; | |
} | |
+ bool operator()(text_symbolizer const&) const | |
+ { | |
+// FIXME: this is true in the sense that a text can be drawn along a path, should check if that is the case and return accordingly | |
+ return false; | |
+ } | |
}; | |
bool is_path_based(symbolizer const& sym) | |
@@ -92,6 +97,34 @@ bool is_path_based(symbolizer const& sym) | |
return util::apply_visitor(symbol_type_dispatch(), sym); | |
} | |
+ | |
+struct symbol_type_dispatch2 | |
+{ | |
+ template <typename Symbolizer> | |
+ bool operator()(Symbolizer const&) const | |
+ { | |
+ return false; | |
+ } | |
+ bool operator()(line_symbolizer const&) const | |
+ { | |
+ return false; | |
+ } | |
+ bool operator()(polygon_symbolizer const&) const | |
+ { | |
+ return false; | |
+ } | |
+ bool operator()(text_symbolizer const&) const | |
+ { | |
+ // FIXME: this is true in the sense that a text can be drawn along a path, should check if that is the case and return accordingly | |
+ return true; | |
+ } | |
+ }; | |
+ | |
+ bool is_text_based(symbolizer const& sym) | |
+ { | |
+ return util::apply_visitor(symbol_type_dispatch2(), sym); | |
+ } | |
+ | |
template <typename OutputIterator, typename PathType> | |
void generate_path_impl(OutputIterator & output_iterator, PathType const& path, svg::path_output_attributes const& path_attributes) | |
{ | |
@@ -102,7 +135,9 @@ void generate_path_impl(OutputIterator & output_iterator, PathType const& path, | |
static const svg::svg_path_generator<OutputIterator,PathType> svg_path_grammer; | |
boost::spirit::karma::lit_type lit; | |
boost::spirit::karma::generate(output_iterator, lit("<path ") << svg_path_grammer, path); | |
- boost::spirit::karma::generate(output_iterator, lit(" ") << dash_array_grammar, path_attributes.stroke_dasharray()); | |
+ if (path_attributes.stroke_dasharray()) { | |
+ boost::spirit::karma::generate(output_iterator, lit(" ") << dash_array_grammar, *(path_attributes.stroke_dasharray())); | |
+ } | |
boost::spirit::karma::generate(output_iterator, lit(" ") << attributes_grammar << lit("/>\n"), path_attributes); | |
} | |
@@ -125,22 +160,24 @@ bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms, | |
process_path = true; | |
} | |
util::apply_visitor(symbolizer_dispatch<svg_renderer<OutputIterator>>(*this, feature, prj_trans), sym); | |
+ // in the case of multiple line symbolizers for this rule need to generate multiple paths for each feature | |
+ if (process_path) | |
+ { | |
+ // generate path output for each geometry of the current feature. | |
+ auto const& geom = feature.get_geometry(); | |
+ path_type path; | |
+ path.set_type(static_cast<path_type::types>(mapnik::util::to_ds_type(geom))); | |
+ geometry::to_path(geom, path); | |
+ vertex_adapter va(path); | |
+ trans_path_type trans_path(common_.t_, va, prj_trans); | |
+ generate_path_impl(generator_.output_iterator_, trans_path, path_attributes_); | |
+ // set the previously collected values back to their defaults | |
+ // for the feature that will be processed next. | |
+ path_attributes_.reset(); | |
+ } | |
} | |
- if (process_path) | |
- { | |
- // generate path output for each geometry of the current feature. | |
- auto const& geom = feature.get_geometry(); | |
- path_type path; | |
- path.set_type(static_cast<path_type::types>(mapnik::util::to_ds_type(geom))); | |
- geometry::to_path(geom, path); | |
- vertex_adapter va(path); | |
- trans_path_type trans_path(common_.t_, va, prj_trans); | |
- generate_path_impl(generator_.output_iterator_, trans_path, path_attributes_); | |
- // set the previously collected values back to their defaults | |
- // for the feature that will be processed next. | |
- path_attributes_.reset(); | |
- } | |
+ | |
return true; | |
} | |
diff --git a/src/svg/output/svg_generator.cpp b/src/svg/output/svg_generator.cpp | |
index cb8eb79..c18f3e0 100644 | |
--- a/src/svg/output/svg_generator.cpp | |
+++ b/src/svg/output/svg_generator.cpp | |
@@ -112,7 +112,7 @@ namespace mapnik { namespace svg { | |
karma::lit_type lit; | |
karma::generate(output_iterator_, lit("</g>\n")); | |
} | |
- | |
+ | |
template class svg_generator<std::ostream_iterator<char> >; | |
}} | |
diff --git a/src/svg/output/svg_output_attributes.cpp b/src/svg/output/svg_output_attributes.cpp | |
index bf05d87..45a5831 100644 | |
--- a/src/svg/output/svg_output_attributes.cpp | |
+++ b/src/svg/output/svg_output_attributes.cpp | |
@@ -93,7 +93,7 @@ namespace mapnik { namespace svg { | |
} | |
} | |
- void path_output_attributes::set_stroke_dasharray(dash_array const& stroke_dasharray) | |
+ void path_output_attributes::set_stroke_dasharray(boost::optional<dash_array> stroke_dasharray) | |
{ | |
stroke_dasharray_ = stroke_dasharray; | |
} | |
@@ -138,7 +138,7 @@ namespace mapnik { namespace svg { | |
return stroke_linejoin_; | |
} | |
- dash_array const& path_output_attributes::stroke_dasharray() const | |
+ boost::optional<dash_array> path_output_attributes::stroke_dasharray() const | |
{ | |
return stroke_dasharray_; | |
} | |
@@ -157,7 +157,7 @@ namespace mapnik { namespace svg { | |
stroke_width_ = 0.0; | |
stroke_linecap_ = "butt"; | |
stroke_linejoin_ = "miter"; | |
- stroke_dasharray_.clear(); | |
+ stroke_dasharray_ = boost::none; | |
stroke_dashoffset_ = 0.0; | |
} | |
@@ -222,7 +222,7 @@ namespace mapnik { namespace svg { | |
fill_color_ = "#000000"; | |
} | |
- // rect_output_attributes | |
+ // root_output_attributes | |
const double root_output_attributes::SVG_VERSION = 1.1; | |
const std::string root_output_attributes::SVG_NAMESPACE_URL = "http://www.w3.org/2000/svg"; | |
@@ -288,6 +288,236 @@ namespace mapnik { namespace svg { | |
svg_version_ = SVG_VERSION; | |
svg_namespace_url_ = SVG_NAMESPACE_URL; | |
} | |
- }} | |
-#endif | |
+ // | |
+ // text_output_attributes | |
+ // | |
+ | |
+ void text_output_attributes::set_text_ratio(const double ratio) { | |
+ text_ratio_ = ratio; | |
+ } | |
+ | |
+ void text_output_attributes::set_face_name(const std::string &name) { | |
+ face_name_ = name; | |
+ } | |
+ | |
+ void text_output_attributes::set_fontset(const std::string &name) { | |
+ fontset_ = name; | |
+ } | |
+ | |
+ void text_output_attributes::set_text_size(const double size) { | |
+ text_size_ = size; | |
+ } | |
+ | |
+ void text_output_attributes::set_char_spacing(const double &space) { | |
+ char_spacing_ = space; | |
+ } | |
+ | |
+ void text_output_attributes::set_text_transform(const text_transform_e &trans) { | |
+ switch(trans) { | |
+ case text_transform_enum::NONE: | |
+ case text_transform_enum::UPPERCASE: | |
+ case text_transform_enum::LOWERCASE: | |
+ case text_transform_enum::CAPITALIZE: | |
+ case text_transform_enum::text_transform_enum_MAX: | |
+ default: | |
+ break; | |
+ } | |
+ } | |
+ | |
+ double text_output_attributes::text_ratio() const { | |
+ return text_ratio_; | |
+ } | |
+ | |
+ std::string text_output_attributes::face_name() const { | |
+ return face_name_; | |
+ } | |
+ | |
+ std::string text_output_attributes::fontset() const { | |
+ return fontset_; | |
+ } | |
+ | |
+ double text_output_attributes::text_size() const { | |
+ return text_size_; | |
+ } | |
+ | |
+ double text_output_attributes::char_spacing() const { | |
+ return char_spacing_; | |
+ } | |
+ | |
+ std::string text_output_attributes::transform() const { | |
+ return transform_; | |
+ } | |
+ | |
+ void text_output_attributes::reset() { | |
+ text_ratio_ = 0; | |
+ text_size_ = 10; | |
+ char_spacing_ = 0; | |
+ transform_ = "none"; | |
+ } | |
+ | |
+ // | |
+ // text_output_attributes_fill | |
+ // | |
+ | |
+ void text_output_attributes_fill::set_fill(const color &fill) { | |
+ fill_ = fill.to_string(); | |
+ | |
+ //fill_ = fill.to_hex_string_no_alpha(); | |
+ fill_opacity_ = fill.alpha()/(double)(0xff); | |
+ } | |
+ | |
+ std::string text_output_attributes_fill::fill() const { | |
+ return fill_; | |
+ } | |
+ | |
+ double text_output_attributes_fill::fill_opacity() const { | |
+ return fill_opacity_; | |
+ } | |
+ | |
+ void text_output_attributes_fill::reset() { | |
+ static_cast<text_output_attributes*>(this)->reset(); | |
+ fill_ = "#000000"; | |
+ fill_opacity_ = 1.0; | |
+ } | |
+ | |
+ // | |
+ // text_output_attributes_stroke | |
+ // | |
+ | |
+ void text_output_attributes_stroke::set_halo_fill(const color &fill) { | |
+// FIXME: rgba() isn't fully supported, fill and alpha is probably better | |
+// halo_fill_ = fill.to_hex_string_no_alpha(); | |
+ halo_fill_ = fill.to_string(); | |
+ stroke_opacity_ = fill.alpha()/(double)(0xff); | |
+ } | |
+ | |
+ void text_output_attributes_stroke::set_halo_radius(const double &radius) { | |
+ halo_radius_ = radius; | |
+ } | |
+ | |
+ std::string text_output_attributes_stroke::halo_fill() const { | |
+ return halo_fill_; | |
+ } | |
+ | |
+ double text_output_attributes_stroke::stroke_opacity() const { | |
+ return stroke_opacity_; | |
+ } | |
+ | |
+ double text_output_attributes_stroke::halo_radius() const { | |
+ return halo_radius_; | |
+ } | |
+ | |
+ void text_output_attributes_stroke::reset() { | |
+ static_cast<text_output_attributes*>(this)->reset(); | |
+ halo_fill_ = "#000000"; | |
+ stroke_opacity_ = 1.0; | |
+ halo_radius_ = 1.0; | |
+ } | |
+ | |
+ // point_output_attributes | |
+ void image_output_attributes::set_x(double x) | |
+ { | |
+ x_ = x; | |
+ } | |
+ | |
+ void image_output_attributes::set_y(double y) | |
+ { | |
+ y_ = y; | |
+ } | |
+ | |
+ void image_output_attributes::set_width(double width) | |
+ { | |
+ width_ = width; | |
+ } | |
+ | |
+ void image_output_attributes::set_height(double height) | |
+ { | |
+ height_ = height; | |
+ } | |
+ | |
+ void image_output_attributes::set_href(std::string const& href) | |
+ { | |
+ href_ = href; | |
+ } | |
+ | |
+ void image_output_attributes::set_id(std::string const& id) | |
+ { | |
+ id_ = id; | |
+ } | |
+ | |
+ double image_output_attributes::x() const | |
+ { | |
+ return x_; | |
+ } | |
+ | |
+ double image_output_attributes::y() const | |
+ { | |
+ return y_; | |
+ } | |
+ | |
+ double image_output_attributes::width() const | |
+ { | |
+ return width_; | |
+ } | |
+ | |
+ double image_output_attributes::height() const | |
+ { | |
+ return height_; | |
+ } | |
+ | |
+ std::string const& image_output_attributes::href() const | |
+ { | |
+ return href_; | |
+ } | |
+ | |
+ void image_output_attributes::reset() | |
+ { | |
+ x_ = 0.0; | |
+ y_ = 0.0; | |
+ width_ = 16.0; | |
+ height_ = 16.0; | |
+ href_ = ""; | |
+ } | |
+ | |
+ // use_output_attributes | |
+ void use_output_attributes::set_x(double x) | |
+ { | |
+ x_ = x; | |
+ } | |
+ | |
+ void use_output_attributes::set_y(double y) | |
+ { | |
+ y_ = y; | |
+ } | |
+ | |
+ void use_output_attributes::set_href(std::string const& href) | |
+ { | |
+ href_ = href; | |
+ } | |
+ | |
+ double use_output_attributes::x() const | |
+ { | |
+ return x_; | |
+ } | |
+ | |
+ double use_output_attributes::y() const | |
+ { | |
+ return y_; | |
+ } | |
+ | |
+ | |
+ std::string const& use_output_attributes::href() const | |
+ { | |
+ return href_; | |
+ } | |
+ | |
+ void use_output_attributes::reset() | |
+ { | |
+ x_ = 0.0; | |
+ y_ = 0.0; | |
+ href_ = ""; | |
+ } | |
+ | |
+ }} | |
+#endif // defined(SVG_RENDERER) | |
diff --git a/src/svg/output/svg_output_grammars.cpp b/src/svg/output/svg_output_grammars.cpp | |
index 398c41a..8f21884 100644 | |
--- a/src/svg/output/svg_output_grammars.cpp | |
+++ b/src/svg/output/svg_output_grammars.cpp | |
@@ -29,3 +29,8 @@ template struct mapnik::svg::svg_path_attributes_grammar<std::ostream_iterator<c | |
template struct mapnik::svg::svg_path_dash_array_grammar<std::ostream_iterator<char> >; | |
template struct mapnik::svg::svg_rect_attributes_grammar<std::ostream_iterator<char> >; | |
template struct mapnik::svg::svg_root_attributes_grammar<std::ostream_iterator<char> >; | |
+template struct mapnik::svg::svg_text_attributes_grammar<std::ostream_iterator<char> >; | |
+template struct mapnik::svg::svg_text_fill_attributes_grammar<std::ostream_iterator<char> >; | |
+template struct mapnik::svg::svg_text_stroke_attributes_grammar<std::ostream_iterator<char> >; | |
+template struct mapnik::svg::svg_image_attributes_grammar<std::ostream_iterator<char> >; | |
+template struct mapnik::svg::svg_use_attributes_grammar<std::ostream_iterator<char> >; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment