Skip to content

Instantly share code, notes, and snippets.

@jc101
Last active February 27, 2016 11:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jc101/f318c4bceb8a6c5f6d6e to your computer and use it in GitHub Desktop.
Save jc101/f318c4bceb8a6c5f6d6e to your computer and use it in GitHub Desktop.
Basic text and point support for Mapnik (branch 1d981e899bed8103740a59c48954621cda7f3f36)
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