Skip to content

Instantly share code, notes, and snippets.

@springmeyer
Forked from isti757/svgoutputmapnik
Created July 24, 2014 00:49
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 springmeyer/2778d7c64b301c9e2aa5 to your computer and use it in GitHub Desktop.
Save springmeyer/2778d7c64b301c9e2aa5 to your computer and use it in GitHub Desktop.
diff --git a/include/mapnik/color.hpp b/include/mapnik/color.hpp
index f21ef76..b6c45cb 100644
--- a/include/mapnik/color.hpp
+++ b/include/mapnik/color.hpp
@@ -28,6 +28,7 @@
#include <mapnik/global.hpp>
//boost
+#include <boost/cstdint.hpp>
#include <boost/operators.hpp>
// stl
@@ -71,6 +72,7 @@ public:
std::string to_string() const;
std::string to_hex_string() const;
+ std::string to_hex_string_no_alpha() const;
void premultiply();
void demultiply();
diff --git a/include/mapnik/svg/output/svg_generator.hpp b/include/mapnik/svg/output/svg_generator.hpp
index 656f650..4250fb3 100644
--- a/include/mapnik/svg/output/svg_generator.hpp
+++ b/include/mapnik/svg/output/svg_generator.hpp
@@ -57,6 +57,10 @@ namespace mapnik { namespace svg {
typedef svg::svg_rect_attributes_grammar<OutputIterator> rect_attributes_grammar;
typedef svg::svg_path_attributes_grammar<OutputIterator> path_attributes_grammar;
typedef svg::svg_path_dash_array_grammar<OutputIterator> path_dash_array_grammar;
+ typedef svg::svg_text_attributes_grammar<OutputIterator> text_attributes_grammar;
+ typedef svg::svg_text_fill_attributes_grammar<OutputIterator> text_fill_attributes_grammar;
+ typedef svg::svg_text_stroke_attributes_grammar<OutputIterator> text_stroke_attributes_grammar;
+
public:
explicit svg_generator(OutputIterator& output_iterator);
@@ -80,7 +84,39 @@ namespace mapnik { namespace svg {
karma::generate(output_iterator_, lit(" ") << dash_array_grammar, path_attributes.stroke_dasharray());
karma::generate(output_iterator_, lit(" ") << attributes_grammar << lit("/>\n"), path_attributes);
}
+ template <typename PathType>
+ void generate_text_on_path(value_unicode_string const& str, text_output_attributes_fill const &text_attr,
+ text_output_attributes_stroke const &text_halo_attr, PathType const &path,
+ path_output_attributes const &attr)
+ {
+ // assign some id to the path
+ int path_id = rand();
+
+ // create path definition
+ karma::generate(output_iterator_, lit("<defs>") << lit("<path id=\"p") << int_ << lit("\" "), path_id);
+
+ util::svg_generator<OutputIterator,PathType> svg_path_grammer;
+ karma::generate(output_iterator_, svg_path_grammer, path);
+
+ path_attributes_grammar attributes_grammar;
+ karma::generate(output_iterator_, lit(" ") << attributes_grammar << lit("/>\n</defs>\n"), attr);
+ // convert text to utf as this is the default xml encoding
+ std::string utf8;
+ to_utf8(str, utf8);
+
+ // default value of stroke in svg is 1, so do not output a halo if the radius is 1
+ text_stroke_attributes_grammar halo_grammar;
+ if(text_halo_attr.halo_radius() != 1.0) {
+ karma::generate(output_iterator_, lit("<text ") << halo_grammar << ">", text_halo_attr);
+ karma::generate(output_iterator_, lit("\n<textPath xlink:href=\"#p") << int_ << lit("\">\n"), path_id);
+ karma::generate(output_iterator_, utf8 << lit("\n</textPath>\n</text>\n"));
+ }
+ text_fill_attributes_grammar text_grammar;
+ karma::generate(output_iterator_, lit("<text ") << text_grammar << ">", text_attr);
+ karma::generate(output_iterator_, lit("\n<textPath xlink:href=\"#p") << int_ << lit("\">\n"), path_id);
+ karma::generate(output_iterator_, utf8 << lit("\n</textPath>\n</text>\n"));
+ }
private:
OutputIterator& output_iterator_;
};
diff --git a/include/mapnik/svg/output/svg_output_attributes.hpp b/include/mapnik/svg/output/svg_output_attributes.hpp
index eb1e8b6..eb3bf14 100644
--- a/include/mapnik/svg/output/svg_output_attributes.hpp
+++ b/include/mapnik/svg/output/svg_output_attributes.hpp
@@ -26,6 +26,7 @@
// mapnik
#include <mapnik/color.hpp>
#include <mapnik/symbolizer.hpp>
+#include <mapnik/text/text_properties.hpp>
// stl
#include <string>
@@ -196,6 +197,123 @@ 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_;
+ };
}}
#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 802b803..28b772c 100644
--- a/include/mapnik/svg/output/svg_output_grammars.hpp
+++ b/include/mapnik/svg/output/svg_output_grammars.hpp
@@ -31,6 +31,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;
} }
// boost
@@ -88,6 +91,49 @@ BOOST_FUSION_ADAPT_STRUCT(
(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, fontset_)
+ (double, text_size_)
+ (std::string, fill_)
+ (double, fill_opacity_)
+ (std::string, halo_fill_)
+ (double, stroke_opacity_)
+ (double, halo_radius_)
+ (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, fontset_)
+ (double, text_size_)
+ (std::string, fill_)
+ (double, fill_opacity_)
+ (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_stroke,
+ (std::string, fontset_)
+ (double, text_size_)
+ (std::string, halo_fill_)
+ (double, stroke_opacity_)
+ (double, halo_radius_)
+ (std::string, transform_)
+ )
+
namespace mapnik { namespace svg {
using namespace boost::spirit;
@@ -177,12 +223,77 @@ struct svg_root_attributes_grammar : karma::grammar<OutputIterator, mapnik::svg:
<< lit(" height=") << confix('"', '"')[int_ << lit("px")]
<< " version=" << confix('"', '"')[double_]
<< " xmlns=" << confix('"', '"')[kstring]
- << lit(" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"");
+ << lit(" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"")
+ << lit(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"");
}
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()
+ : svg_text_attributes_grammar::base_type(svg_text_attributes)
+ {
+ karma::lit_type lit;
+ karma::string_type kstring;
+ karma::double_type double_;
+ repository::confix_type confix;
+
+ svg_text_attributes =
+ lit(" font-family=") << confix('"', '"')[kstring]
+ << lit(" font-size=") << confix('"', '"')[double_ << lit("px")]
+ << lit(" fill=") << confix('"', '"')[kstring] << lit(" fill-opacity=") << confix('"', '"')[double_]
+ << lit(" style=\"") << lit("stroke: ") << kstring << lit("; stroke-opacity: ") << double_ << "; stroke-width: " << double_ << lit("\"")
+ << lit(" text-transform=") << confix('"', '"')[kstring];
+ }
+
+ 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()
+ : svg_text_fill_attributes_grammar::base_type(svg_text_attributes_fill)
+ {
+ karma::lit_type lit;
+ karma::string_type kstring;
+ karma::double_type double_;
+ repository::confix_type confix;
+
+ svg_text_attributes_fill =
+ lit(" font-family=") << confix('"', '"')[kstring]
+ << lit(" font-size=") << confix('"', '"')[double_ << lit("px")]
+ << lit(" fill=") << confix('"', '"')[kstring] << lit(" fill-opacity=") << confix('"', '"')[double_]
+ << lit(" text-transform=") << confix('"', '"')[kstring];
+ }
+
+ 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()
+ : svg_text_stroke_attributes_grammar::base_type(svg_text_attributes_stroke)
+ {
+ karma::lit_type lit;
+ karma::string_type kstring;
+ karma::double_type double_;
+ repository::confix_type confix;
+
+ svg_text_attributes_stroke =
+ lit(" font-family=") << confix('"', '"')[kstring]
+ << lit(" font-size=") << confix('"', '"')[double_ << lit("px")]
+ << lit(" fill=\"none\"")
+ << lit(" style=\"") << lit("stroke: ") << kstring << lit("; stroke-opacity: ") << double_ << "; stroke-width: " << double_ << lit("\"")
+ << lit(" text-transform=") << confix('"', '"')[kstring];
+ }
+
+ karma::rule<OutputIterator, mapnik::svg::text_output_attributes_stroke()> svg_text_attributes_stroke;
+};
+ }}
#endif // SVG_OUTPUT_GRAMMARS_HPP
diff --git a/include/mapnik/text/glyph_info.hpp b/include/mapnik/text/glyph_info.hpp
index a387045..644c6b3 100644
--- a/include/mapnik/text/glyph_info.hpp
+++ b/include/mapnik/text/glyph_info.hpp
@@ -23,6 +23,7 @@
#define MAPNIK_GLYPH_INFO_HPP
//mapnik
+#include <mapnik/value.hpp>
#include <mapnik/text/char_properties_ptr.hpp>
#include <mapnik/pixel_position.hpp>
@@ -47,7 +48,8 @@ struct glyph_info
ymax(0.0),
line_height(0.0),
offset(),
- format() {}
+ format(),
+ orig(0) {}
glyph_index_t glyph_index;
face_ptr face;
// Position in the string of all characters i.e. before itemizing
@@ -61,6 +63,7 @@ struct glyph_info
pixel_position offset;
char_properties_ptr format;
double height() const { return ymax-ymin; }
+ std::shared_ptr<value_unicode_string> orig;
};
} //ns mapnik
diff --git a/include/mapnik/text/harfbuzz_shaper.hpp b/include/mapnik/text/harfbuzz_shaper.hpp
index 2b0c5f9..bd6275d 100644
--- a/include/mapnik/text/harfbuzz_shaper.hpp
+++ b/include/mapnik/text/harfbuzz_shaper.hpp
@@ -97,6 +97,8 @@ static void shape_text(text_line & line,
continue;
}
+ std::shared_ptr<value_unicode_string> curr_item(new value_unicode_string());
+ text.extract(text_item.start, text_item.end - text_item.start, *curr_item.get());
for (unsigned i=0; i<num_glyphs; ++i)
{
glyph_info tmp;
@@ -109,6 +111,7 @@ static void shape_text(text_line & line,
tmp.width = positions[i].x_advance >> 6;
tmp.offset.set(positions[i].x_offset / 64.0, positions[i].y_offset / 64.0);
width_map[glyphs[i].cluster] += tmp.width;
+ tmp.orig = curr_item;
line.add_glyph(tmp, scale_factor);
}
line.update_max_char_height(face->get_char_height());
diff --git a/include/mapnik/text/icu_shaper.hpp b/include/mapnik/text/icu_shaper.hpp
index db5246a..35641a5 100644
--- a/include/mapnik/text/icu_shaper.hpp
+++ b/include/mapnik/text/icu_shaper.hpp
@@ -90,6 +90,8 @@ static void shape_text(text_line & line,
{
U_NAMESPACE_QUALIFIER StringCharacterIterator iter(shaped);
unsigned i = 0;
+ std::shared_ptr<value_unicode_string> curr_item(new value_unicode_string());
+ text.extract(text_item.start, text_item.end - text_item.start, *curr_item.get());
for (iter.setToStart(); iter.hasNext();)
{
UChar ch = iter.nextPostInc();
@@ -104,6 +106,7 @@ static void shape_text(text_line & line,
}
tmp.face = face;
tmp.format = text_item.format;
+ tmp.orig = curr_item;
face->glyph_dimensions(tmp);
width_map[i] += tmp.width;
line.add_glyph(tmp, scale_factor);
diff --git a/include/mapnik/value_types.hpp b/include/mapnik/value_types.hpp
index 6807906..c78e46f 100644
--- a/include/mapnik/value_types.hpp
+++ b/include/mapnik/value_types.hpp
@@ -23,6 +23,10 @@
#ifndef MAPNIK_VALUE_TYPES_HPP
#define MAPNIK_VALUE_TYPES_HPP
+#ifndef BOOST_SPIRIT_UNICODE
+#define BOOST_SPIRIT_UNICODE
+#endif
+
// icu
#include <unicode/unistr.h> // for UnicodeString
diff --git a/src/color.cpp b/src/color.cpp
index 1b8a87d..d833dba 100644
--- a/src/color.cpp
+++ b/src/color.cpp
@@ -91,6 +91,26 @@ std::string color::to_hex_string() const
return str;
}
+std::string color::to_hex_string_no_alpha() 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()]]
+ // end grammar
+ );
+ return str;
+}
+
void color::premultiply()
{
agg::rgba8 pre_c = agg::rgba8(red_,green_,blue_,alpha_);
diff --git a/src/svg/output/process_text_symbolizer.cpp b/src/svg/output/process_text_symbolizer.cpp
index b21f24d..e2cc70f 100644
--- a/src/svg/output/process_text_symbolizer.cpp
+++ b/src/svg/output/process_text_symbolizer.cpp
@@ -24,15 +24,130 @@
// mapnik
#include <mapnik/svg/output/svg_renderer.hpp>
+#include <mapnik/text/symbolizer_helpers.hpp>
namespace mapnik
{
+// extends a curve at both endpoints such that the resulting curve
+// is smooth at the endpoints and hopefully matches the profile of the curve
+// in the background. this needs to be done because the path outputted
+// by the shapers does not always fit the text when rendered not by mapnik
+void extend_curve(int num_pts, std::deque<double> &x, std::deque<double> &y) {
+ if(x.size() > 1 && y.size() > 1) {
+ double dx1 = x[0]-x[1], dy1 = y[0]-y[1];
+ for(int i = 0; i < num_pts; i++) {
+ x.push_front(x[0]+dx1*(i+1));
+ y.push_front(y[0]+dy1*(i+1));
+ }
+
+ int len = x.size();
+ double dx2 = x[len-1]-x[len-2], dy2 = y[len-1]-y[len-2];
+ for(int i = 0; i < num_pts; i++) {
+ x.push_back(x[len-1]+dx2*(i+1));
+ y.push_back(y[len-1]+dy2*(i+1));
+ }
+ }
+}
+
template <typename T>
void svg_renderer<T>::process(text_symbolizer const& sym,
mapnik::feature_impl & feature,
proj_transform const& prj_trans)
{
- // nothing yet.
+ typedef coord_transform<CoordTransform, geometry_type> path_type;
+
+ double inf = std::numeric_limits<double>::max();
+ box2d<double> clip_box(-inf, -inf, inf, inf);
+
+ // find positions for all the glyphs
+ text_symbolizer_helper helper(
+ sym, feature, prj_trans,
+ common_.width_, common_.height_,
+ common_.scale_factor_,
+ common_.t_, common_.font_manager_, *common_.detector_,
+ clip_box);
+
+ // leave the path attributes empty
+ svg::path_output_attributes line_attr;
+
+ // halo effect is emulated by having 2 copies of the
+ // text. one with fill only, one with stroke only
+ // it can be done with filters but there are libraries
+ // that don't support filter (especially in android)
+ svg::text_output_attributes_fill text_attr;
+ text_attr.set_text_ratio(sym.get_text_ratio());
+ text_attr.set_face_name(sym.get_face_name());
+ if(sym.get_fontset())
+ text_attr.set_fontset(sym.get_fontset()->get_name());
+ text_attr.set_text_size(get<double>(sym, keys::text_size, feature));
+ text_attr.set_fill(get<mapnik::color>(sym, keys::fill, feature));
+ text_attr.set_char_spacing(sym.get_character_spacing());
+ text_attr.set_text_transform(sym.get_text_transform());
+
+ // the halo duplicate of the text
+ svg::text_output_attributes_stroke halo_attr;
+ halo_attr.set_text_ratio(sym.get_text_ratio());
+ halo_attr.set_face_name(sym.get_face_name());
+ if(sym.get_fontset()) {
+ halo_attr.set_fontset(sym.get_fontset()->get_name());
+ }
+ halo_attr.set_text_size(sym.get_text_size());
+ halo_attr.set_halo_fill(sym.get_halo_fill());
+ // default stroke width in svg is 1.0
+ halo_attr.set_halo_radius(1.0+sym.get_halo_radius());
+ halo_attr.set_char_spacing(sym.get_character_spacing());
+ halo_attr.set_text_transform(sym.get_text_transform());
+
+ // extract glyph positions
+ placements_list const& placements = helper.get();
+ for (glyph_positions_ptr glyphs : placements)
+ {
+ // reconstruct geometry for text placing
+ std::deque<double> x,y;
+ value_unicode_string prev = "";
+ if(glyphs->begin() != glyphs->end())
+ prev = *(glyphs->begin()->glyph->orig.get());
+ pixel_position base = glyphs->get_base_point(); base.y = height_-base.y;
+ for(auto it = glyphs->begin(); it != glyphs->end(); ++it)
+ {
+ value_unicode_string curr = *(it->glyph->orig.get());
+ if(curr != prev) {
+ // create geometry from the accumulated positions
+ extend_curve(1, x, y);
+ geometry_type geom(geometry_type::LineString);
+ for(int i = 0; i < x.size(); i++) {
+ if(i == 0)
+ geom.move_to(x[i], y[i]);
+ else
+ geom.line_to(x[i], y[i]);
+ }
+
+ generator_.generate_text_on_path(prev, text_attr, halo_attr, geom, line_attr);
+ prev = curr;
+
+ x.clear(); y.clear();
+ }
+
+ // determine position of character in the string
+ pixel_position pos = it->pos+it->glyph->offset.rotate(it->rot)+base;
+ // translate to svg coordinate space
+ x.push_back(pos.x);
+ y.push_back(height_-pos.y);
+ }
+
+ // create text on geometry specified by the glyph positions
+ if(x.size() > 0) {
+ extend_curve(1, x, y);
+ geometry_type geom(geometry_type::LineString);
+ for(int i = 0; i < x.size(); i++) {
+ if(i == 0)
+ geom.move_to(x[i], y[i]);
+ else
+ geom.line_to(x[i], y[i]);
+ }
+ generator_.generate_text_on_path(prev, text_attr, halo_attr, geom, line_attr);
+ }
+ }
}
template void svg_renderer<std::ostream_iterator<char> >::process(text_symbolizer const& sym,
diff --git a/src/svg/output/svg_output_attributes.cpp b/src/svg/output/svg_output_attributes.cpp
index 972fbb7..d61eaec 100644
--- a/src/svg/output/svg_output_attributes.cpp
+++ b/src/svg/output/svg_output_attributes.cpp
@@ -289,7 +289,129 @@ 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::NONE:
+ case text_transform::UPPERCASE:
+ case text_transform::LOWERCASE:
+ case text_transform::CAPITALIZE:
+ case text_transform::text_transform_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_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) {
+ halo_fill_ = fill.to_hex_string_no_alpha();
+ 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;
+ }
+
+ }}
+#endif // defined(SVG_RENDERER)
\ No newline at end of file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment