Merge pull request #2138 from MapQuest/jmh-text-layouts
Multiple text layouts in text symbolizer
|
@ -33,6 +33,7 @@
|
|||
#include <mapnik/text/formatting/list.hpp>
|
||||
#include <mapnik/text/formatting/format.hpp>
|
||||
#include <mapnik/text/formatting/expression_format.hpp>
|
||||
#include <mapnik/text/formatting/layout.hpp>
|
||||
#include <mapnik/text/layout.hpp>
|
||||
#include <mapnik/text_symbolizer.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
@ -97,12 +98,12 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
boost::python::tuple get_displacement(text_symbolizer_properties const& t)
|
||||
boost::python::tuple get_displacement(text_layout_properties const& t)
|
||||
{
|
||||
return boost::python::make_tuple(t.displacement.x, t.displacement.y);
|
||||
}
|
||||
|
||||
void set_displacement(text_symbolizer_properties &t, boost::python::tuple arg)
|
||||
void set_displacement(text_layout_properties &t, boost::python::tuple arg)
|
||||
{
|
||||
if (len(arg) != 2)
|
||||
{
|
||||
|
@ -118,7 +119,6 @@ void set_displacement(text_symbolizer_properties &t, boost::python::tuple arg)
|
|||
t.displacement.set(x, y);
|
||||
}
|
||||
|
||||
|
||||
struct NodeWrap: formatting::node, wrapper<formatting::node>
|
||||
{
|
||||
NodeWrap() : formatting::node(), wrapper<formatting::node>()
|
||||
|
@ -225,6 +225,27 @@ struct ExprFormatWrap: formatting::expression_format, wrapper<formatting::expres
|
|||
}
|
||||
};
|
||||
|
||||
struct LayoutNodeWrap: formatting::layout_node, wrapper<formatting::layout_node>
|
||||
{
|
||||
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const
|
||||
{
|
||||
if(override o = this->get_override("apply"))
|
||||
{
|
||||
python_block_auto_unblock b;
|
||||
o(ptr(&p), ptr(&feature), ptr(&output));
|
||||
}
|
||||
else
|
||||
{
|
||||
formatting::layout_node::apply(p, feature, output);
|
||||
}
|
||||
}
|
||||
|
||||
void default_apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const
|
||||
{
|
||||
formatting::layout_node::apply(p, feature, output);
|
||||
}
|
||||
};
|
||||
|
||||
struct ListNodeWrap: formatting::list_node, wrapper<formatting::list_node>
|
||||
{
|
||||
//Default constructor
|
||||
|
@ -399,13 +420,7 @@ void export_text_placement()
|
|||
class_with_converter<text_symbolizer_properties>
|
||||
("TextSymbolizerProperties")
|
||||
.def_readwrite_convert("label_placement", &text_symbolizer_properties::label_placement)
|
||||
.def_readwrite_convert("horizontal_alignment", &text_symbolizer_properties::halign)
|
||||
.def_readwrite_convert("justify_alignment", &text_symbolizer_properties::jalign)
|
||||
.def_readwrite_convert("vertical_alignment", &text_symbolizer_properties::valign)
|
||||
.def_readwrite("orientation", &text_symbolizer_properties::orientation)
|
||||
.add_property("displacement",
|
||||
&get_displacement,
|
||||
&set_displacement)
|
||||
.def_readwrite_convert("upright", &text_symbolizer_properties::upright)
|
||||
.def_readwrite("label_spacing", &text_symbolizer_properties::label_spacing)
|
||||
.def_readwrite("label_position_tolerance", &text_symbolizer_properties::label_position_tolerance)
|
||||
.def_readwrite("avoid_edges", &text_symbolizer_properties::avoid_edges)
|
||||
|
@ -416,9 +431,7 @@ void export_text_placement()
|
|||
.def_readwrite("force_odd_labels", &text_symbolizer_properties::force_odd_labels)
|
||||
.def_readwrite("allow_overlap", &text_symbolizer_properties::allow_overlap)
|
||||
.def_readwrite("largest_bbox_only", &text_symbolizer_properties::largest_bbox_only)
|
||||
.def_readwrite("text_ratio", &text_symbolizer_properties::text_ratio)
|
||||
.def_readwrite("wrap_width", &text_symbolizer_properties::wrap_width)
|
||||
.def_readwrite("wrap_before", &text_symbolizer_properties::wrap_before)
|
||||
.def_readwrite("layout_defaults", &text_symbolizer_properties::layout_defaults)
|
||||
.def_readwrite("format", &text_symbolizer_properties::format)
|
||||
.add_property ("format_tree",
|
||||
&text_symbolizer_properties::format_tree,
|
||||
|
@ -430,6 +443,17 @@ void export_text_placement()
|
|||
set_old_style expression is just a compatibility wrapper and doesn't need to be exposed in python. */
|
||||
;
|
||||
|
||||
class_with_converter<text_layout_properties>
|
||||
("TextLayoutProperties")
|
||||
.def_readwrite_convert("horizontal_alignment", &text_layout_properties::halign)
|
||||
.def_readwrite_convert("justify_alignment", &text_layout_properties::jalign)
|
||||
.def_readwrite_convert("vertical_alignment", &text_layout_properties::valign)
|
||||
.def_readwrite("text_ratio", &text_layout_properties::text_ratio)
|
||||
.def_readwrite("wrap_width", &text_layout_properties::wrap_width)
|
||||
.def_readwrite("wrap_before", &text_layout_properties::wrap_before)
|
||||
.def_readwrite("orientation", &text_layout_properties::orientation)
|
||||
.def_readwrite("rotate_displacement", &text_layout_properties::rotate_displacement)
|
||||
.add_property("displacement", &get_displacement, &set_displacement);
|
||||
|
||||
class_with_converter<char_properties>
|
||||
("CharProperties")
|
||||
|
|
59
include/mapnik/text/formatting/layout.hpp
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2013 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef FORMATTING_OFFSET_HPP
|
||||
#define FORMATTING_OFFSET_HPP
|
||||
|
||||
#include <mapnik/text/formatting/base.hpp>
|
||||
#include <mapnik/text/text_properties.hpp>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
namespace formatting {
|
||||
class MAPNIK_DECL layout_node: public node {
|
||||
public:
|
||||
void to_xml(boost::property_tree::ptree &xml) const;
|
||||
static node_ptr from_xml(xml_node const& xml);
|
||||
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const;
|
||||
virtual void add_expressions(expression_set &output) const;
|
||||
void set_child(node_ptr child);
|
||||
node_ptr get_child() const;
|
||||
|
||||
boost::optional<double> dx;
|
||||
boost::optional<double> dy;
|
||||
boost::optional<horizontal_alignment_e> halign;
|
||||
boost::optional<vertical_alignment_e> valign;
|
||||
boost::optional<justify_alignment_e> jalign;
|
||||
boost::optional<double> text_ratio;
|
||||
boost::optional<double> wrap_width;
|
||||
boost::optional<bool> wrap_before;
|
||||
boost::optional<bool> rotate_displacement;
|
||||
boost::optional<expression_ptr> orientation;
|
||||
|
||||
private:
|
||||
node_ptr child_;
|
||||
};
|
||||
} //ns formatting
|
||||
} //ns mapnik
|
||||
|
||||
#endif // FORMATTING_OFFSET_HPP
|
|
@ -30,6 +30,7 @@
|
|||
#include <mapnik/text/harfbuzz_shaper.hpp>
|
||||
#include <mapnik/text/icu_shaper.hpp>
|
||||
#include <mapnik/text/dummy_shaper.hpp>
|
||||
#include <mapnik/text/rotation.hpp>
|
||||
|
||||
//stl
|
||||
#include <vector>
|
||||
|
@ -38,13 +39,17 @@
|
|||
namespace mapnik
|
||||
{
|
||||
|
||||
typedef std::shared_ptr<text_layout> text_layout_ptr;
|
||||
typedef std::vector<text_layout_ptr> text_layout_vector;
|
||||
|
||||
class text_layout
|
||||
{
|
||||
public:
|
||||
typedef std::vector<text_line> line_vector;
|
||||
typedef line_vector::const_iterator const_iterator;
|
||||
typedef text_layout_vector::const_iterator child_iterator;
|
||||
typedef harfbuzz_shaper shaper_type;
|
||||
text_layout(face_manager_freetype & font_manager, double scale_factor);
|
||||
text_layout(face_manager_freetype & font_manager, double scale_factor, text_layout_properties_ptr properties);
|
||||
|
||||
/** Adds a new text part. Call this function repeatedly to build the complete text. */
|
||||
void add_text(mapnik::value_unicode_string const& str, char_properties_ptr format);
|
||||
|
@ -53,7 +58,7 @@ public:
|
|||
mapnik::value_unicode_string const& text() const;
|
||||
|
||||
/** Processes the text into a list of glyphs, performing RTL/LTR handling, shaping and line breaking. */
|
||||
void layout(double wrap_width, unsigned text_ratio, bool wrap_before);
|
||||
void layout();
|
||||
|
||||
/** Clear all data stored in this object. The object's state is the same as directly after construction. */
|
||||
void clear();
|
||||
|
@ -81,11 +86,29 @@ public:
|
|||
// Returns the number of glyphs so memory can be preallocated.
|
||||
inline unsigned glyphs_count() const { return glyphs_count_;}
|
||||
|
||||
void add_child(text_layout_ptr child_layout);
|
||||
|
||||
inline const text_layout_vector &get_child_layouts() const { return child_layout_list_; }
|
||||
|
||||
inline face_manager<freetype_engine> &get_font_manager() const { return font_manager_; }
|
||||
inline double get_scale_factor() const { return scale_factor_; }
|
||||
inline text_layout_properties_ptr get_layout_properties() const { return properties_; }
|
||||
|
||||
inline rotation const& orientation() const { return orientation_; }
|
||||
inline pixel_position const& displacement() const { return displacement_; }
|
||||
inline box2d<double> const& bounds() const { return bounds_; }
|
||||
|
||||
pixel_position alignment_offset() const;
|
||||
double jalign_offset(double line_width) const;
|
||||
|
||||
void init_orientation(feature_impl const& feature);
|
||||
|
||||
private:
|
||||
void break_line(text_line & line, double wrap_width, unsigned text_ratio, bool wrap_before);
|
||||
void shape_text(text_line & line);
|
||||
void add_line(text_line & line);
|
||||
void clear_cluster_widths(unsigned first, unsigned last);
|
||||
void init_alignment();
|
||||
|
||||
//input
|
||||
face_manager_freetype &font_manager_;
|
||||
|
@ -103,7 +126,60 @@ private:
|
|||
|
||||
//output
|
||||
line_vector lines_;
|
||||
|
||||
//text layout properties
|
||||
text_layout_properties_ptr properties_;
|
||||
|
||||
//alignments
|
||||
vertical_alignment_e valign_;
|
||||
horizontal_alignment_e halign_;
|
||||
justify_alignment_e jalign_;
|
||||
|
||||
// Precalculated values for maximum performance
|
||||
rotation orientation_;
|
||||
pixel_position displacement_;
|
||||
box2d<double> bounds_;
|
||||
|
||||
//children
|
||||
text_layout_vector child_layout_list_;
|
||||
};
|
||||
|
||||
class layout_container
|
||||
{
|
||||
public:
|
||||
layout_container() : glyphs_count_(0), line_count_(0) {}
|
||||
|
||||
void add(text_layout_ptr layout);
|
||||
void clear();
|
||||
|
||||
void layout();
|
||||
|
||||
inline size_t size() const { return layouts_.size(); }
|
||||
|
||||
inline text_layout_vector::const_iterator begin() const { return layouts_.begin(); }
|
||||
inline text_layout_vector::const_iterator end() const { return layouts_.end(); }
|
||||
|
||||
inline mapnik::value_unicode_string const& text() const { return text_; }
|
||||
|
||||
inline unsigned glyphs_count() const { return glyphs_count_; }
|
||||
inline unsigned line_count() const { return line_count_; }
|
||||
|
||||
inline box2d<double> const& bounds() const { return bounds_; }
|
||||
|
||||
inline double width() const { return bounds_.width(); }
|
||||
inline double height() const { return bounds_.height(); }
|
||||
|
||||
private:
|
||||
text_layout_vector layouts_;
|
||||
|
||||
mapnik::value_unicode_string text_;
|
||||
|
||||
unsigned glyphs_count_;
|
||||
unsigned line_count_;
|
||||
|
||||
box2d<double> bounds_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TEXT_LAYOUT_HPP
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <mapnik/text/placements/base.hpp>
|
||||
#include <mapnik/text/placements_list.hpp>
|
||||
#include <mapnik/text/rotation.hpp>
|
||||
#include <mapnik/text/vertex_cache.hpp>
|
||||
#include <mapnik/noncopyable.hpp>
|
||||
|
||||
namespace mapnik
|
||||
|
@ -62,10 +63,6 @@ public:
|
|||
|
||||
void set_marker(marker_info_ptr m, box2d<double> box, bool marker_unlocked, pixel_position const& marker_displacement);
|
||||
private:
|
||||
void init_alignment();
|
||||
pixel_position alignment_offset() const;
|
||||
double jalign_offset(double line_width) const;
|
||||
|
||||
bool single_line_placement(vertex_cache &pp, text_upright_e orientation);
|
||||
/** Moves dx pixels but makes sure not to fall of the end. */
|
||||
void path_move_dx(vertex_cache &pp);
|
||||
|
@ -80,23 +77,16 @@ private:
|
|||
/** Maps upright==auto, left_only and right_only to left,right to simplify processing.
|
||||
angle = angle of at start of line (to estimate best option for upright==auto) */
|
||||
text_upright_e simplify_upright(text_upright_e upright, double angle) const;
|
||||
box2d<double> get_bbox(glyph_info const& glyph, pixel_position const& pos, rotation const& rot);
|
||||
box2d<double> get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot);
|
||||
feature_impl const& feature_;
|
||||
DetectorType &detector_;
|
||||
box2d<double> const& extent_;
|
||||
// Precalculated values for maximum performance
|
||||
rotation orientation_;
|
||||
text_layout layout_;
|
||||
text_placement_info_ptr info_;
|
||||
layout_container layouts_;
|
||||
bool valid_;
|
||||
|
||||
vertical_alignment_e valign_;
|
||||
/** Horizontal alignment for point placements. */
|
||||
horizontal_alignment_e halign_point_;
|
||||
/** Horizontal alignment for line placements. */
|
||||
horizontal_alignment_e halign_line_;
|
||||
justify_alignment_e jalign_;
|
||||
double scale_factor_;
|
||||
face_manager_freetype &font_manager_;
|
||||
|
||||
placements_list placements_;
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ struct rotation
|
|||
void init(double angle) { sin = std::sin(angle); cos = std::cos(angle); }
|
||||
double sin;
|
||||
double cos;
|
||||
rotation operator~() { return rotation(sin, -cos); }
|
||||
rotation operator!() { return rotation(-sin, cos); }
|
||||
rotation operator~() const { return rotation(sin, -cos); }
|
||||
rotation operator!() const { return rotation(-sin, cos); }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -132,10 +132,36 @@ enum text_upright
|
|||
|
||||
DEFINE_ENUM(text_upright_e, text_upright);
|
||||
|
||||
/** Properties for building the layout of a single text placement */
|
||||
struct MAPNIK_DECL text_layout_properties
|
||||
{
|
||||
text_layout_properties();
|
||||
|
||||
/** Load all values from XML ptree. */
|
||||
void from_xml(xml_node const &sym);
|
||||
/** Save all values to XML ptree (but does not create a new parent node!). */
|
||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, text_layout_properties const &dfl=text_layout_properties()) const;
|
||||
|
||||
/** Get a list of all expressions used in any placement.
|
||||
* This function is used to collect attributes. */
|
||||
void add_expressions(expression_set &output) const;
|
||||
|
||||
//Per layout options
|
||||
expression_ptr orientation;
|
||||
pixel_position displacement;
|
||||
horizontal_alignment_e halign;
|
||||
justify_alignment_e jalign;
|
||||
vertical_alignment_e valign;
|
||||
double text_ratio;
|
||||
double wrap_width;
|
||||
bool wrap_before;
|
||||
bool rotate_displacement;
|
||||
};
|
||||
typedef std::shared_ptr<text_layout_properties> text_layout_properties_ptr;
|
||||
|
||||
class text_layout;
|
||||
|
||||
|
||||
/** Contains all text symbolizer properties which are not directly related to text formatting. */
|
||||
/** Contains all text symbolizer properties which are not directly related to text formatting and layout. */
|
||||
struct MAPNIK_DECL text_symbolizer_properties
|
||||
{
|
||||
text_symbolizer_properties();
|
||||
|
@ -159,12 +185,7 @@ struct MAPNIK_DECL text_symbolizer_properties
|
|||
void add_expressions(expression_set &output) const;
|
||||
|
||||
//Per symbolizer options
|
||||
expression_ptr orientation;
|
||||
pixel_position displacement;
|
||||
label_placement_e label_placement;
|
||||
horizontal_alignment_e halign;
|
||||
justify_alignment_e jalign;
|
||||
vertical_alignment_e valign;
|
||||
/** distance between repeated labels on a single geometry */
|
||||
double label_spacing;
|
||||
/** distance the label can be moved on the line to fit, if 0 the default is used */
|
||||
|
@ -179,11 +200,11 @@ struct MAPNIK_DECL text_symbolizer_properties
|
|||
bool allow_overlap;
|
||||
/** Only consider geometry with largest bbox (polygons) */
|
||||
bool largest_bbox_only;
|
||||
double text_ratio;
|
||||
double wrap_width;
|
||||
bool wrap_before;
|
||||
bool rotate_displacement;
|
||||
text_upright_e upright;
|
||||
|
||||
/** Default values for text layouts */
|
||||
text_layout_properties_ptr layout_defaults;
|
||||
|
||||
/** Default values for char_properties. */
|
||||
char_properties_ptr format;
|
||||
private:
|
||||
|
|
|
@ -226,6 +226,7 @@ source = Split(
|
|||
text/formatting/list.cpp
|
||||
text/formatting/text.cpp
|
||||
text/formatting/format.cpp
|
||||
text/formatting/layout.cpp
|
||||
text/formatting/registry.cpp
|
||||
text/placements/registry.cpp
|
||||
text/placements/base.cpp
|
||||
|
|
125
src/text/formatting/layout.cpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 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/text/text_properties.hpp>
|
||||
#include <mapnik/text/layout.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/expression_string.hpp>
|
||||
#include <mapnik/text/formatting/layout.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
namespace formatting {
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
void layout_node::to_xml(ptree &xml) const
|
||||
{
|
||||
ptree &new_node = xml.push_back(ptree::value_type("Layout", ptree()))->second;
|
||||
|
||||
if (dx) set_attr(new_node, "dx", *dx);
|
||||
if (dy) set_attr(new_node, "dy", *dy);
|
||||
if (halign) set_attr(new_node, "horizontal-alignment", *halign);
|
||||
if (valign) set_attr(new_node, "vertical-alignment", *valign);
|
||||
if (jalign) set_attr(new_node, "justify-alignment", *jalign);
|
||||
if (text_ratio) set_attr(new_node, "text-ratio", *text_ratio);
|
||||
if (wrap_width) set_attr(new_node, "wrap-width", *wrap_width);
|
||||
if (wrap_before) set_attr(new_node, "wrap-before", *wrap_before);
|
||||
if (rotate_displacement) set_attr(new_node, "rotate-displacement", *rotate_displacement);
|
||||
if (orientation) set_attr(new_node, "orientation", to_expression_string(**orientation));
|
||||
|
||||
if (child_) child_->to_xml(new_node);
|
||||
}
|
||||
|
||||
node_ptr layout_node::from_xml(xml_node const& xml)
|
||||
{
|
||||
std::shared_ptr<layout_node> n = std::make_shared<layout_node>();
|
||||
|
||||
node_ptr child = node::from_xml(xml);
|
||||
n->set_child(child);
|
||||
|
||||
n->dx = xml.get_opt_attr<double>("dx");
|
||||
n->dy = xml.get_opt_attr<double>("dy");
|
||||
n->halign = xml.get_opt_attr<horizontal_alignment_e>("horizontal-alignment");
|
||||
n->valign = xml.get_opt_attr<vertical_alignment_e>("vertical-alignment");
|
||||
n->jalign = xml.get_opt_attr<justify_alignment_e>("justify-alignment");
|
||||
n->text_ratio = xml.get_opt_attr<double>("text-ratio");
|
||||
n->wrap_width = xml.get_opt_attr<double>("wrap-width");
|
||||
n->wrap_before = xml.get_opt_attr<boolean>("wrap-before");
|
||||
n->rotate_displacement = xml.get_opt_attr<boolean>("rotate-displacement");
|
||||
n->orientation = xml.get_opt_attr<expression_ptr>("orientation");
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void layout_node::apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const
|
||||
{
|
||||
text_layout_properties_ptr new_properties = std::make_shared<text_layout_properties>(*output.get_layout_properties());
|
||||
if (dx) new_properties->displacement.x = *dx;
|
||||
if (dy) new_properties->displacement.y = *dy;
|
||||
if (halign) new_properties->halign = *halign;
|
||||
if (valign) new_properties->valign = *valign;
|
||||
if (jalign) new_properties->jalign = *jalign;
|
||||
if (text_ratio) new_properties->text_ratio = *text_ratio;
|
||||
if (wrap_width) new_properties->wrap_width = *wrap_width;
|
||||
if (wrap_before) new_properties->wrap_before = *wrap_before;
|
||||
if (rotate_displacement) new_properties->rotate_displacement = *rotate_displacement;
|
||||
if (orientation) new_properties->orientation = *orientation;
|
||||
|
||||
// starting a new offset child with the new displacement value
|
||||
text_layout_ptr child_layout = std::make_shared<text_layout>(output.get_font_manager(), output.get_scale_factor(), new_properties);
|
||||
child_layout->init_orientation(feature);
|
||||
|
||||
// process contained format tree into the child node
|
||||
if (child_) {
|
||||
child_->apply(p, feature, *child_layout);
|
||||
} else {
|
||||
MAPNIK_LOG_WARN(format) << "Useless layout node: Contains no text";
|
||||
}
|
||||
output.add_child(child_layout);
|
||||
}
|
||||
|
||||
void layout_node::set_child(node_ptr child)
|
||||
{
|
||||
child_ = child;
|
||||
}
|
||||
|
||||
node_ptr layout_node::get_child() const
|
||||
{
|
||||
return child_;
|
||||
}
|
||||
|
||||
void layout_node::add_expressions(expression_set &output) const
|
||||
{
|
||||
if (child_) child_->add_expressions(output);
|
||||
}
|
||||
|
||||
} //ns formatting
|
||||
} //ns mapnik
|
|
@ -24,6 +24,7 @@
|
|||
#include <mapnik/text/formatting/text.hpp>
|
||||
#include <mapnik/text/formatting/format.hpp>
|
||||
#include <mapnik/text/formatting/expression_format.hpp>
|
||||
#include <mapnik/text/formatting/layout.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
|
@ -37,6 +38,7 @@ registry::registry()
|
|||
register_name("<xmltext>", &text_node::from_xml);
|
||||
register_name("Format", &format_node::from_xml);
|
||||
register_name("ExpressionFormat", &expression_format::from_xml);
|
||||
register_name("Layout", &layout_node::from_xml);
|
||||
}
|
||||
|
||||
void registry::register_name(std::string const& name, from_xml_function_ptr ptr, bool overwrite)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <mapnik/text/layout.hpp>
|
||||
#include <mapnik/text/text_properties.hpp>
|
||||
#include <mapnik/expression_evaluator.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
|
||||
// ICU
|
||||
|
@ -30,7 +31,29 @@
|
|||
namespace mapnik
|
||||
{
|
||||
|
||||
text_layout::text_layout(face_manager_freetype & font_manager, double scale_factor)
|
||||
// Output is centered around (0,0)
|
||||
static void rotated_box2d(box2d<double> & box, rotation const& rot, pixel_position const& center, double width, double height)
|
||||
{
|
||||
double half_width, half_height;
|
||||
if (rot.sin == 0 && rot.cos == 1.)
|
||||
{
|
||||
half_width = width / 2.;
|
||||
half_height = height / 2.;
|
||||
}
|
||||
else
|
||||
{
|
||||
half_width = (width * rot.cos + height * rot.sin) /2.;
|
||||
half_height = (width * rot.sin + height * rot.cos) /2.;
|
||||
}
|
||||
box.init(center.x - half_width, center.y - half_height, center.x + half_width, center.y + half_height);
|
||||
}
|
||||
|
||||
pixel_position pixel_position::rotate(rotation const& rot) const
|
||||
{
|
||||
return pixel_position(x * rot.cos - y * rot.sin, x * rot.sin + y * rot.cos);
|
||||
}
|
||||
|
||||
text_layout::text_layout(face_manager_freetype & font_manager, double scale_factor, text_layout_properties_ptr properties)
|
||||
: font_manager_(font_manager),
|
||||
scale_factor_(scale_factor),
|
||||
itemizer_(),
|
||||
|
@ -38,7 +61,8 @@ text_layout::text_layout(face_manager_freetype & font_manager, double scale_fact
|
|||
width_(0.0),
|
||||
height_(0.0),
|
||||
glyphs_count_(0),
|
||||
lines_()
|
||||
lines_(),
|
||||
properties_(properties)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -47,20 +71,34 @@ void text_layout::add_text(mapnik::value_unicode_string const& str, char_propert
|
|||
itemizer_.add_text(str, format);
|
||||
}
|
||||
|
||||
void text_layout::add_child(text_layout_ptr child_layout)
|
||||
{
|
||||
child_layout_list_.push_back(child_layout);
|
||||
}
|
||||
|
||||
mapnik::value_unicode_string const& text_layout::text() const
|
||||
{
|
||||
return itemizer_.text();
|
||||
}
|
||||
|
||||
void text_layout::layout(double wrap_width, unsigned text_ratio, bool wrap_before)
|
||||
void text_layout::layout()
|
||||
{
|
||||
unsigned num_lines = itemizer_.num_lines();
|
||||
for (unsigned i = 0; i < num_lines; ++i)
|
||||
{
|
||||
std::pair<unsigned, unsigned> line_limits = itemizer_.line(i);
|
||||
text_line line(line_limits.first, line_limits.second);
|
||||
break_line(line, wrap_width, text_ratio, wrap_before); //Break line if neccessary
|
||||
//Break line if neccessary
|
||||
break_line(line, properties_->wrap_width * scale_factor_, properties_->text_ratio, properties_->wrap_before);
|
||||
}
|
||||
init_alignment();
|
||||
|
||||
/* Find text origin. */
|
||||
displacement_ = scale_factor_ * properties_->displacement + alignment_offset();
|
||||
if (properties_->rotate_displacement) displacement_ = displacement_.rotate(!orientation_);
|
||||
|
||||
/* Find layout bounds, expanded for rotation */
|
||||
rotated_box2d(bounds_, orientation_, displacement_, width_, height_);
|
||||
}
|
||||
|
||||
/* In the Unicode string characters are always stored in logical order.
|
||||
|
@ -189,6 +227,7 @@ void text_layout::clear()
|
|||
width_map_.clear();
|
||||
width_ = 0.;
|
||||
height_ = 0.;
|
||||
child_layout_list_.clear();
|
||||
}
|
||||
|
||||
void text_layout::shape_text(text_line & line)
|
||||
|
@ -196,5 +235,155 @@ void text_layout::shape_text(text_line & line)
|
|||
shaper_type::shape_text(line, itemizer_, width_map_, font_manager_, scale_factor_);
|
||||
}
|
||||
|
||||
void text_layout::init_orientation(feature_impl const& feature)
|
||||
{
|
||||
if (properties_->orientation)
|
||||
{
|
||||
// https://github.com/mapnik/mapnik/issues/1352
|
||||
mapnik::evaluate<feature_impl, value_type> evaluator(feature);
|
||||
orientation_.init(
|
||||
boost::apply_visitor(
|
||||
evaluator,
|
||||
*(properties_->orientation)).to_double() * M_PI / 180.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
orientation_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void text_layout::init_alignment()
|
||||
{
|
||||
text_layout_properties const& p = *(properties_);
|
||||
valign_ = p.valign;
|
||||
if (valign_ == V_AUTO)
|
||||
{
|
||||
if (p.displacement.y > 0.0)
|
||||
{
|
||||
valign_ = V_BOTTOM;
|
||||
}
|
||||
else if (p.displacement.y < 0.0)
|
||||
{
|
||||
valign_ = V_TOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
valign_ = V_MIDDLE;
|
||||
}
|
||||
}
|
||||
|
||||
halign_ = p.halign;
|
||||
if (halign_ == H_AUTO)
|
||||
{
|
||||
if (p.displacement.x > 0.0)
|
||||
{
|
||||
halign_ = H_RIGHT;
|
||||
}
|
||||
else if (p.displacement.x < 0.0)
|
||||
{
|
||||
halign_ = H_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
halign_ = H_MIDDLE;
|
||||
}
|
||||
}
|
||||
|
||||
jalign_ = p.jalign;
|
||||
if (jalign_ == J_AUTO)
|
||||
{
|
||||
if (p.displacement.x > 0.0)
|
||||
{
|
||||
jalign_ = J_LEFT;
|
||||
}
|
||||
else if (p.displacement.x < 0.0)
|
||||
{
|
||||
jalign_ = J_RIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
jalign_ = J_MIDDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pixel_position text_layout::alignment_offset() const
|
||||
{
|
||||
pixel_position result(0,0);
|
||||
// if needed, adjust for desired vertical alignment
|
||||
if (valign_ == V_TOP)
|
||||
{
|
||||
result.y = -0.5 * height(); // move center up by 1/2 the total height
|
||||
}
|
||||
else if (valign_ == V_BOTTOM)
|
||||
{
|
||||
result.y = 0.5 * height(); // move center down by the 1/2 the total height
|
||||
}
|
||||
// set horizontal position to middle of text
|
||||
if (halign_ == H_LEFT)
|
||||
{
|
||||
result.x = -0.5 * width(); // move center left by 1/2 the string width
|
||||
}
|
||||
else if (halign_ == H_RIGHT)
|
||||
{
|
||||
result.x = 0.5 * width(); // move center right by 1/2 the string width
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double text_layout::jalign_offset(double line_width) const
|
||||
{
|
||||
if (jalign_ == J_MIDDLE) return -(line_width / 2.0);
|
||||
if (jalign_ == J_LEFT) return -(width() / 2.0);
|
||||
if (jalign_ == J_RIGHT) return (width() / 2.0) - line_width;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void layout_container::add(text_layout_ptr layout)
|
||||
{
|
||||
text_ += layout->text();
|
||||
layouts_.push_back(layout);
|
||||
|
||||
for (text_layout_ptr const& child_layout : layout->get_child_layouts())
|
||||
{
|
||||
add(child_layout);
|
||||
}
|
||||
}
|
||||
|
||||
void layout_container::layout()
|
||||
{
|
||||
bounds_.init(0,0,0,0);
|
||||
glyphs_count_ = 0;
|
||||
line_count_ = 0;
|
||||
|
||||
bool first = true;
|
||||
for (text_layout_ptr const& layout : layouts_)
|
||||
{
|
||||
layout->layout();
|
||||
|
||||
glyphs_count_ += layout->glyphs_count();
|
||||
line_count_ += layout->num_lines();
|
||||
|
||||
if (first)
|
||||
{
|
||||
bounds_ = layout->bounds();
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_.expand_to_include(layout->bounds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void layout_container::clear()
|
||||
{
|
||||
layouts_.clear();
|
||||
text_.remove();
|
||||
bounds_.init(0,0,0,0);
|
||||
glyphs_count_ = 0;
|
||||
line_count_ = 0;
|
||||
}
|
||||
|
||||
|
||||
} //ns mapnik
|
||||
|
|
|
@ -107,19 +107,6 @@ private:
|
|||
};
|
||||
|
||||
|
||||
// Output is centered around (0,0)
|
||||
static void rotated_box2d(box2d<double> & box, rotation const& rot, double width, double height)
|
||||
{
|
||||
double new_width = width * rot.cos + height * rot.sin;
|
||||
double new_height = width * rot.sin + height * rot.cos;
|
||||
box.init(-new_width/2., -new_height/2., new_width/2., new_height/2.);
|
||||
}
|
||||
|
||||
pixel_position pixel_position::rotate(rotation const& rot) const
|
||||
{
|
||||
return pixel_position(x * rot.cos - y * rot.sin, x * rot.sin + y * rot.cos);
|
||||
}
|
||||
|
||||
placement_finder::placement_finder(feature_impl const& feature,
|
||||
DetectorType &detector,
|
||||
box2d<double> const& extent,
|
||||
|
@ -129,10 +116,10 @@ placement_finder::placement_finder(feature_impl const& feature,
|
|||
: feature_(feature),
|
||||
detector_(detector),
|
||||
extent_(extent),
|
||||
layout_(font_manager, scale_factor),
|
||||
info_(placement_info),
|
||||
valid_(true),
|
||||
scale_factor_(scale_factor),
|
||||
font_manager_(font_manager),
|
||||
placements_(),
|
||||
has_marker_(false),
|
||||
marker_(),
|
||||
|
@ -153,173 +140,113 @@ bool placement_finder::next_position()
|
|||
return false;
|
||||
}
|
||||
|
||||
info_->properties.process(layout_, feature_);
|
||||
layout_.layout(info_->properties.wrap_width * scale_factor_, info_->properties.text_ratio, info_->properties.wrap_before);
|
||||
text_layout_ptr layout = std::make_shared<text_layout>(font_manager_, scale_factor_, info_->properties.layout_defaults);
|
||||
layout->init_orientation(feature_);
|
||||
info_->properties.process(*layout, feature_);
|
||||
|
||||
layouts_.clear();
|
||||
layouts_.add(layout);
|
||||
layouts_.layout();
|
||||
|
||||
if (info_->properties.orientation)
|
||||
{
|
||||
// https://github.com/mapnik/mapnik/issues/1352
|
||||
mapnik::evaluate<feature_impl, value_type> evaluator(feature_);
|
||||
orientation_.init(
|
||||
boost::apply_visitor(
|
||||
evaluator,
|
||||
*(info_->properties.orientation)).to_double() * M_PI / 180.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
orientation_.reset();
|
||||
}
|
||||
init_alignment();
|
||||
return true;
|
||||
}
|
||||
|
||||
void placement_finder::init_alignment()
|
||||
text_upright_e placement_finder::simplify_upright(text_upright_e upright, double angle) const
|
||||
{
|
||||
text_symbolizer_properties const& p = info_->properties;
|
||||
valign_ = p.valign;
|
||||
if (valign_ == V_AUTO)
|
||||
if (upright == UPRIGHT_AUTO)
|
||||
{
|
||||
if (p.displacement.y > 0.0)
|
||||
{
|
||||
valign_ = V_BOTTOM;
|
||||
}
|
||||
else if (p.displacement.y < 0.0)
|
||||
{
|
||||
valign_ = V_TOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
valign_ = V_MIDDLE;
|
||||
}
|
||||
return (std::fabs(normalize_angle(angle)) > 0.5*M_PI) ? UPRIGHT_LEFT : UPRIGHT_RIGHT;
|
||||
}
|
||||
|
||||
halign_point_ = p.halign;
|
||||
halign_line_ = p.halign;
|
||||
if (halign_point_ == H_AUTO)
|
||||
if (upright == UPRIGHT_LEFT_ONLY)
|
||||
{
|
||||
if (p.displacement.x > 0.0)
|
||||
{
|
||||
halign_point_ = H_RIGHT;
|
||||
halign_line_ = H_LEFT;
|
||||
}
|
||||
else if (p.displacement.x < 0.0)
|
||||
{
|
||||
halign_point_ = H_LEFT;
|
||||
halign_line_= H_RIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
halign_point_ = H_MIDDLE;
|
||||
halign_line_ = H_MIDDLE;
|
||||
}
|
||||
return UPRIGHT_LEFT;
|
||||
}
|
||||
|
||||
jalign_ = p.jalign;
|
||||
if (jalign_ == J_AUTO)
|
||||
if (upright == UPRIGHT_RIGHT_ONLY)
|
||||
{
|
||||
if (p.displacement.x > 0.0)
|
||||
{
|
||||
jalign_ = J_LEFT;
|
||||
}
|
||||
else if (p.displacement.x < 0.0)
|
||||
{
|
||||
jalign_ = J_RIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
jalign_ = J_MIDDLE;
|
||||
}
|
||||
return UPRIGHT_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pixel_position placement_finder::alignment_offset() const //TODO
|
||||
{
|
||||
pixel_position result(0,0);
|
||||
// if needed, adjust for desired vertical alignment
|
||||
if (valign_ == V_TOP)
|
||||
{
|
||||
result.y = -0.5 * layout_.height(); // move center up by 1/2 the total height
|
||||
}
|
||||
else if (valign_ == V_BOTTOM)
|
||||
{
|
||||
result.y = 0.5 * layout_.height(); // move center down by the 1/2 the total height
|
||||
}
|
||||
|
||||
// set horizontal position to middle of text
|
||||
if (halign_point_ == H_LEFT)
|
||||
{
|
||||
result.x = -0.5 * layout_.width(); // move center left by 1/2 the string width
|
||||
}
|
||||
else if (halign_point_ == H_RIGHT)
|
||||
{
|
||||
result.x = 0.5 * layout_.width(); // move center right by 1/2 the string width
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double placement_finder::jalign_offset(double line_width) const //TODO
|
||||
{
|
||||
if (jalign_ == J_MIDDLE) return -(line_width / 2.0);
|
||||
if (jalign_ == J_LEFT) return -(layout_.width() / 2.0);
|
||||
if (jalign_ == J_RIGHT) return (layout_.width() / 2.0) - line_width;
|
||||
return 0;
|
||||
return upright;
|
||||
}
|
||||
|
||||
bool placement_finder::find_point_placement(pixel_position const& pos)
|
||||
{
|
||||
glyph_positions_ptr glyphs = std::make_shared<glyph_positions>();
|
||||
std::vector<box2d<double> > bboxes;
|
||||
|
||||
/* Find text origin. */
|
||||
pixel_position displacement = scale_factor_ * info_->properties.displacement + alignment_offset();
|
||||
if (info_->properties.rotate_displacement) displacement = displacement.rotate(!orientation_);
|
||||
glyphs->set_base_point(pos + displacement);
|
||||
box2d<double> bbox;
|
||||
rotated_box2d(bbox, orientation_, layout_.width(), layout_.height());
|
||||
bbox.re_center(glyphs->get_base_point().x, glyphs->get_base_point().y);
|
||||
glyphs->reserve(layouts_.glyphs_count());
|
||||
bboxes.reserve(layouts_.size());
|
||||
|
||||
/* For point placements it is faster to just check the bounding box. */
|
||||
if (collision(bbox)) return false;
|
||||
/* add_marker first checks for collision and then updates the detector.*/
|
||||
if (has_marker_ && !add_marker(glyphs, pos)) return false;
|
||||
if (layout_.num_lines()) detector_.insert(bbox, layout_.text());
|
||||
|
||||
/* IMPORTANT NOTE:
|
||||
x and y are relative to the center of the text
|
||||
coordinate system:
|
||||
x: grows from left to right
|
||||
y: grows from bottom to top (opposite of normal computer graphics)
|
||||
*/
|
||||
double x, y;
|
||||
|
||||
// set for upper left corner of text envelope for the first line, top left of first character
|
||||
y = layout_.height() / 2.0;
|
||||
glyphs->reserve(layout_.glyphs_count());
|
||||
|
||||
for ( auto const& line : layout_)
|
||||
bool base_point_set = false;
|
||||
for (auto const& layout_ptr : layouts_)
|
||||
{
|
||||
y -= line.height(); //Automatically handles first line differently
|
||||
x = jalign_offset(line.width());
|
||||
text_layout const& layout = *layout_ptr;
|
||||
rotation const& orientation = layout.orientation();
|
||||
|
||||
for (auto const& glyph : line)
|
||||
/* Find text origin. */
|
||||
pixel_position layout_center = pos + layout.displacement();
|
||||
|
||||
if (!base_point_set)
|
||||
{
|
||||
// place the character relative to the center of the string envelope
|
||||
glyphs->push_back(glyph, pixel_position(x, y).rotate(orientation_), orientation_);
|
||||
if (glyph.width)
|
||||
glyphs->set_base_point(layout_center);
|
||||
base_point_set = true;
|
||||
}
|
||||
|
||||
box2d<double> bbox = layout.bounds();
|
||||
bbox.re_center(layout_center.x, layout_center.y);
|
||||
|
||||
/* For point placements it is faster to just check the bounding box. */
|
||||
if (collision(bbox)) return false;
|
||||
|
||||
if (layout.num_lines()) bboxes.push_back(std::move(bbox));
|
||||
|
||||
pixel_position layout_offset = layout_center - glyphs->get_base_point();
|
||||
layout_offset.y = -layout_offset.y;
|
||||
|
||||
/* IMPORTANT NOTE:
|
||||
x and y are relative to the center of the text
|
||||
coordinate system:
|
||||
x: grows from left to right
|
||||
y: grows from bottom to top (opposite of normal computer graphics)
|
||||
*/
|
||||
double x, y;
|
||||
|
||||
// set for upper left corner of text envelope for the first line, top left of first character
|
||||
y = layout.height() / 2.0;
|
||||
|
||||
for ( auto const& line : layout)
|
||||
{
|
||||
y -= line.height(); //Automatically handles first line differently
|
||||
x = layout.jalign_offset(line.width());
|
||||
|
||||
for (auto const& glyph : line)
|
||||
{
|
||||
//Only advance if glyph is not part of a multiple glyph sequence
|
||||
x += glyph.width + glyph.format->character_spacing * scale_factor_;
|
||||
// place the character relative to the center of the string envelope
|
||||
glyphs->push_back(glyph, (pixel_position(x, y).rotate(orientation)) + layout_offset, orientation);
|
||||
if (glyph.width)
|
||||
{
|
||||
//Only advance if glyph is not part of a multiple glyph sequence
|
||||
x += glyph.width + glyph.format->character_spacing * scale_factor_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add_marker first checks for collision and then updates the detector.*/
|
||||
if (has_marker_ && !add_marker(glyphs, pos)) return false;
|
||||
|
||||
for (box2d<double> const& bbox : bboxes)
|
||||
{
|
||||
detector_.insert(bbox, layouts_.text());
|
||||
}
|
||||
placements_.push_back(glyphs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool placement_finder::find_line_placements(T & path, bool points)
|
||||
{
|
||||
if (!layout_.num_lines()) return true; //TODO
|
||||
if (!layouts_.line_count()) return true; //TODO
|
||||
vertex_cache pp(path);
|
||||
|
||||
bool success = false;
|
||||
|
@ -339,15 +266,15 @@ bool placement_finder::find_line_placements(T & path, bool points)
|
|||
||
|
||||
(pp.length() <= 0.001) /* Clipping removed whole geometry */
|
||||
||
|
||||
(pp.length() < layout_.width()))
|
||||
(pp.length() < layouts_.width()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
double spacing = get_spacing(pp.length(), points ? 0. : layout_.width());
|
||||
double spacing = get_spacing(pp.length(), points ? 0. : layouts_.width());
|
||||
|
||||
horizontal_alignment_e halign = info_->properties.halign;
|
||||
horizontal_alignment_e halign = info_->properties.layout_defaults->halign;
|
||||
if (halign == H_LEFT)
|
||||
{
|
||||
// Don't move
|
||||
|
@ -381,125 +308,116 @@ bool placement_finder::find_line_placements(T & path, bool points)
|
|||
return success;
|
||||
}
|
||||
|
||||
text_upright_e placement_finder::simplify_upright(text_upright_e upright, double angle) const
|
||||
{
|
||||
if (upright == UPRIGHT_AUTO)
|
||||
{
|
||||
return (std::fabs(normalize_angle(angle)) > 0.5*M_PI) ? UPRIGHT_LEFT : UPRIGHT_RIGHT;
|
||||
}
|
||||
if (upright == UPRIGHT_LEFT_ONLY)
|
||||
{
|
||||
return UPRIGHT_LEFT;
|
||||
}
|
||||
if (upright == UPRIGHT_RIGHT_ONLY)
|
||||
{
|
||||
return UPRIGHT_RIGHT;
|
||||
}
|
||||
return upright;
|
||||
}
|
||||
|
||||
|
||||
bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e orientation)
|
||||
{
|
||||
/********************************************************************************
|
||||
* IMPORTANT NOTE: See note about coordinate systems in find_point_placement()! *
|
||||
********************************************************************************/
|
||||
vertex_cache::scoped_state s(pp);
|
||||
vertex_cache::scoped_state begin(pp);
|
||||
text_upright_e real_orientation = simplify_upright(orientation, pp.angle());
|
||||
|
||||
glyph_positions_ptr glyphs = std::make_shared<glyph_positions>();
|
||||
std::vector<box2d<double> > bboxes;
|
||||
bboxes.reserve(layout_.text().length());
|
||||
int upside_down_glyph_count = 0;
|
||||
glyphs->reserve(layouts_.glyphs_count());
|
||||
bboxes.reserve(layouts_.glyphs_count());
|
||||
|
||||
text_upright_e real_orientation = simplify_upright(orientation, pp.angle());
|
||||
unsigned upside_down_glyph_count = 0;
|
||||
|
||||
double sign = (real_orientation == UPRIGHT_LEFT) ? -1 : 1;
|
||||
double offset = alignment_offset().y + info_->properties.displacement.y * scale_factor_ + sign * layout_.height()/2.;
|
||||
|
||||
glyphs->reserve(layout_.glyphs_count());
|
||||
|
||||
for (auto const& line : layout_)
|
||||
for (auto const& layout_ptr : layouts_)
|
||||
{
|
||||
//Only subtract half the line height here and half at the end because text is automatically
|
||||
//centered on the line
|
||||
offset -= sign * line.height()/2;
|
||||
vertex_cache & off_pp = pp.get_offseted(offset, sign*layout_.width());
|
||||
vertex_cache::scoped_state off_state(off_pp); //TODO: Remove this when a clean implementation in vertex_cache::get_offseted was done
|
||||
text_layout const& layout = *layout_ptr;
|
||||
pixel_position align_offset = layout.alignment_offset();
|
||||
pixel_position const& layout_displacement = layout.get_layout_properties()->displacement;
|
||||
double sign = (real_orientation == UPRIGHT_LEFT) ? -1 : 1;
|
||||
double offset = align_offset.y + layout_displacement.y * scale_factor_ + sign * layout.height()/2.;
|
||||
|
||||
if (!off_pp.move(sign * jalign_offset(line.width()) - alignment_offset().x)) return false;
|
||||
|
||||
double last_cluster_angle = 999;
|
||||
int current_cluster = -1;
|
||||
pixel_position cluster_offset;
|
||||
double angle;
|
||||
rotation rot;
|
||||
double last_glyph_spacing = 0.;
|
||||
|
||||
for (auto const& glyph : line)
|
||||
for (auto const& line : layout)
|
||||
{
|
||||
if (current_cluster != static_cast<int>(glyph.char_index))
|
||||
//Only subtract half the line height here and half at the end because text is automatically
|
||||
//centered on the line
|
||||
offset -= sign * line.height()/2;
|
||||
vertex_cache & off_pp = pp.get_offseted(offset, sign*layout.width());
|
||||
vertex_cache::scoped_state off_state(off_pp); //TODO: Remove this when a clean implementation in vertex_cache::get_offseted was done
|
||||
|
||||
if (!off_pp.move(sign * layout.jalign_offset(line.width()) - align_offset.x)) return false;
|
||||
|
||||
double last_cluster_angle = 999;
|
||||
int current_cluster = -1;
|
||||
pixel_position cluster_offset;
|
||||
double angle;
|
||||
rotation rot;
|
||||
double last_glyph_spacing = 0.;
|
||||
|
||||
for (auto const& glyph : line)
|
||||
{
|
||||
if (!off_pp.move(sign * (layout_.cluster_width(current_cluster) + last_glyph_spacing)))
|
||||
if (current_cluster != static_cast<int>(glyph.char_index))
|
||||
{
|
||||
return false;
|
||||
if (!off_pp.move(sign * (layout.cluster_width(current_cluster) + last_glyph_spacing)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
current_cluster = glyph.char_index;
|
||||
last_glyph_spacing = glyph.format->character_spacing * scale_factor_;
|
||||
//Only calculate new angle at the start of each cluster!
|
||||
angle = normalize_angle(off_pp.angle(sign * layout.cluster_width(current_cluster)));
|
||||
rot.init(angle);
|
||||
if ((info_->properties.max_char_angle_delta > 0) && (last_cluster_angle != 999) &&
|
||||
std::fabs(normalize_angle(angle-last_cluster_angle)) > info_->properties.max_char_angle_delta)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
cluster_offset.clear();
|
||||
last_cluster_angle = angle;
|
||||
}
|
||||
current_cluster = glyph.char_index;
|
||||
last_glyph_spacing = glyph.format->character_spacing * scale_factor_;
|
||||
//Only calculate new angle at the start of each cluster!
|
||||
angle = normalize_angle(off_pp.angle(sign * layout_.cluster_width(current_cluster)));
|
||||
rot.init(angle);
|
||||
if ((info_->properties.max_char_angle_delta > 0) && (last_cluster_angle != 999) &&
|
||||
std::fabs(normalize_angle(angle-last_cluster_angle)) > info_->properties.max_char_angle_delta)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
cluster_offset.clear();
|
||||
last_cluster_angle = angle;
|
||||
|
||||
if (std::abs(angle) > M_PI/2) ++upside_down_glyph_count;
|
||||
|
||||
pixel_position pos = off_pp.current_position() + cluster_offset;
|
||||
//Center the text on the line
|
||||
double char_height = line.max_char_height();
|
||||
pos.y = -pos.y - char_height/2.0*rot.cos;
|
||||
pos.x = pos.x + char_height/2.0*rot.sin;
|
||||
|
||||
cluster_offset.x += rot.cos * glyph.width;
|
||||
cluster_offset.y -= rot.sin * glyph.width;
|
||||
|
||||
box2d<double> bbox = get_bbox(layout, glyph, pos, rot);
|
||||
if (collision(bbox)) return false;
|
||||
bboxes.push_back(std::move(bbox));
|
||||
glyphs->push_back(glyph, pos, rot);
|
||||
}
|
||||
if (std::abs(angle) > M_PI/2) ++upside_down_glyph_count;
|
||||
|
||||
pixel_position pos = off_pp.current_position() + cluster_offset;
|
||||
//Center the text on the line
|
||||
double char_height = line.max_char_height();
|
||||
pos.y = -pos.y - char_height/2.0*rot.cos;
|
||||
pos.x = pos.x + char_height/2.0*rot.sin;
|
||||
|
||||
cluster_offset.x += rot.cos * glyph.width;
|
||||
cluster_offset.y -= rot.sin * glyph.width;
|
||||
|
||||
box2d<double> bbox = get_bbox(glyph, pos, rot);
|
||||
if (collision(bbox)) return false;
|
||||
bboxes.push_back(bbox);
|
||||
glyphs->push_back(glyph, pos, rot);
|
||||
//See comment above
|
||||
offset -= sign * line.height()/2;
|
||||
}
|
||||
//See comment above
|
||||
offset -= sign * line.height()/2;
|
||||
}
|
||||
if (upside_down_glyph_count > (layout_.text().length()/2))
|
||||
|
||||
if (upside_down_glyph_count > (layouts_.text().length() / 2))
|
||||
{
|
||||
if (orientation == UPRIGHT_AUTO)
|
||||
{
|
||||
//Try again with oposite orientation
|
||||
s.restore();
|
||||
begin.restore();
|
||||
return single_line_placement(pp, real_orientation == UPRIGHT_RIGHT ? UPRIGHT_LEFT : UPRIGHT_RIGHT);
|
||||
}
|
||||
//upright==left_only or right_only and more than 50% of characters upside down => no placement
|
||||
if (orientation == UPRIGHT_LEFT_ONLY || orientation == UPRIGHT_RIGHT_ONLY)
|
||||
else if (orientation == UPRIGHT_LEFT_ONLY || orientation == UPRIGHT_RIGHT_ONLY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (box2d<double> const& bbox : bboxes)
|
||||
|
||||
for (box2d<double> const& box : bboxes)
|
||||
{
|
||||
detector_.insert(bbox, layout_.text());
|
||||
detector_.insert(box, layouts_.text());
|
||||
}
|
||||
placements_.push_back(glyphs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void placement_finder::path_move_dx(vertex_cache &pp)
|
||||
{
|
||||
double dx = info_->properties.displacement.x * scale_factor_;
|
||||
double dx = info_->properties.layout_defaults->displacement.x * scale_factor_;
|
||||
if (dx != 0.0)
|
||||
{
|
||||
vertex_cache::state state = pp.save_state();
|
||||
|
@ -579,7 +497,7 @@ bool placement_finder::add_marker(glyph_positions_ptr glyphs, pixel_position con
|
|||
return true;
|
||||
}
|
||||
|
||||
box2d<double> placement_finder::get_bbox(glyph_info const& glyph, pixel_position const& pos, rotation const& rot)
|
||||
box2d<double> placement_finder::get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot)
|
||||
{
|
||||
/*
|
||||
|
||||
|
@ -592,7 +510,7 @@ box2d<double> placement_finder::get_bbox(glyph_info const& glyph, pixel_position
|
|||
(0/ymin) (width/ymin)
|
||||
Add glyph offset in y direction, but not in x direction (as we use the full cluster width anyways)!
|
||||
*/
|
||||
double width = layout_.cluster_width(glyph.char_index);
|
||||
double width = layout.cluster_width(glyph.char_index);
|
||||
if (glyph.width <= 0) width = -width;
|
||||
pixel_position tmp, tmp2;
|
||||
tmp.set(0, glyph.ymax);
|
||||
|
|
|
@ -42,6 +42,7 @@ text_placement_info::text_placement_info(text_placements const* parent,
|
|||
scale_factor(scale_factor_)
|
||||
{
|
||||
properties.format = std::make_shared<char_properties>(*(properties.format));
|
||||
properties.layout_defaults = std::make_shared<text_layout_properties>(*(properties.layout_defaults));
|
||||
}
|
||||
|
||||
} //ns mapnik
|
||||
|
|
|
@ -99,6 +99,7 @@ text_placements_ptr text_placements_list::from_xml(xml_node const &xml, fontset_
|
|||
if (itr->is_text() || !itr->is("Placement")) continue;
|
||||
text_symbolizer_properties &p = list->add();
|
||||
p.format = std::make_shared<char_properties>(*(p.format)); //Make a deep copy
|
||||
p.layout_defaults = std::make_shared<text_layout_properties>(*(p.layout_defaults));
|
||||
//TODO: This needs a real copy constructor for text_symbolizer_properties
|
||||
p.from_xml(*itr, fontsets);
|
||||
//TODO: if (strict_ &&
|
||||
|
|
|
@ -61,8 +61,8 @@ bool text_placement_info_simple::next()
|
|||
|
||||
bool text_placement_info_simple::next_position_only()
|
||||
{
|
||||
pixel_position const& pdisp = parent_->defaults.displacement;
|
||||
pixel_position &displacement = properties.displacement;
|
||||
pixel_position const& pdisp = parent_->defaults.layout_defaults->displacement;
|
||||
pixel_position &displacement = properties.layout_defaults->displacement;
|
||||
if (position_state >= parent_->direction_.size()) return false;
|
||||
directions_t dir = parent_->direction_[position_state];
|
||||
switch (dir) {
|
||||
|
|
|
@ -99,12 +99,7 @@ IMPLEMENT_ENUM(text_upright_e, text_upright_strings)
|
|||
*/
|
||||
|
||||
text_symbolizer_properties::text_symbolizer_properties() :
|
||||
orientation(),
|
||||
displacement(0.0,0.0),
|
||||
label_placement(POINT_PLACEMENT),
|
||||
halign(H_AUTO),
|
||||
jalign(J_AUTO),
|
||||
valign(V_AUTO),
|
||||
label_spacing(0.0),
|
||||
label_position_tolerance(0.0),
|
||||
avoid_edges(false),
|
||||
|
@ -115,11 +110,8 @@ text_symbolizer_properties::text_symbolizer_properties() :
|
|||
force_odd_labels(false),
|
||||
allow_overlap(false),
|
||||
largest_bbox_only(true),
|
||||
text_ratio(0.0),
|
||||
wrap_width(0.0),
|
||||
wrap_before(false),
|
||||
rotate_displacement(false),
|
||||
upright(UPRIGHT_AUTO),
|
||||
layout_defaults(std::make_shared<text_layout_properties>()),
|
||||
format(std::make_shared<char_properties>()),
|
||||
tree_()
|
||||
{
|
||||
|
@ -150,14 +142,6 @@ void text_symbolizer_properties::from_xml(xml_node const &sym, fontset_map const
|
|||
{
|
||||
optional<label_placement_e> placement_ = sym.get_opt_attr<label_placement_e>("placement");
|
||||
if (placement_) label_placement = *placement_;
|
||||
optional<vertical_alignment_e> valign_ = sym.get_opt_attr<vertical_alignment_e>("vertical-alignment");
|
||||
if (valign_) valign = *valign_;
|
||||
optional<double> text_ratio_ = sym.get_opt_attr<double>("text-ratio");
|
||||
if (text_ratio_) text_ratio = *text_ratio_;
|
||||
optional<double> wrap_width_ = sym.get_opt_attr<double>("wrap-width");
|
||||
if (wrap_width_) wrap_width = *wrap_width_;
|
||||
optional<boolean> wrap_before_ = sym.get_opt_attr<boolean>("wrap-before");
|
||||
if (wrap_before_) wrap_before = *wrap_before_;
|
||||
optional<double> label_position_tolerance_ = sym.get_opt_attr<double>("label-position-tolerance");
|
||||
if (label_position_tolerance_) label_position_tolerance = *label_position_tolerance_;
|
||||
optional<double> spacing_ = sym.get_opt_attr<double>("spacing");
|
||||
|
@ -179,22 +163,12 @@ void text_symbolizer_properties::from_xml(xml_node const &sym, fontset_map const
|
|||
if (allow_overlap_) allow_overlap = *allow_overlap_;
|
||||
optional<boolean> largest_bbox_only_ = sym.get_opt_attr<boolean>("largest-bbox-only");
|
||||
if (largest_bbox_only_) largest_bbox_only = *largest_bbox_only_;
|
||||
optional<horizontal_alignment_e> halign_ = sym.get_opt_attr<horizontal_alignment_e>("horizontal-alignment");
|
||||
if (halign_) halign = *halign_;
|
||||
optional<justify_alignment_e> jalign_ = sym.get_opt_attr<justify_alignment_e>("justify-alignment");
|
||||
if (jalign_) jalign = *jalign_;
|
||||
optional<expression_ptr> orientation_ = sym.get_opt_attr<expression_ptr>("orientation");
|
||||
if (orientation_) orientation = *orientation_;
|
||||
optional<boolean> rotate_displacement_ = sym.get_opt_attr<boolean>("rotate-displacement");
|
||||
if (rotate_displacement_) rotate_displacement = *rotate_displacement_;
|
||||
optional<text_upright_e> upright_ = sym.get_opt_attr<text_upright_e>("upright");
|
||||
if (upright_) upright = *upright_;
|
||||
optional<double> dx = sym.get_opt_attr<double>("dx");
|
||||
if (dx) displacement.x = *dx;
|
||||
optional<double> dy = sym.get_opt_attr<double>("dy");
|
||||
if (dy) displacement.y = *dy;
|
||||
optional<double> max_char_angle_delta_ = sym.get_opt_attr<double>("max-char-angle-delta");
|
||||
if (max_char_angle_delta_) max_char_angle_delta=(*max_char_angle_delta_)*(M_PI/180);
|
||||
optional<text_upright_e> upright_ = sym.get_opt_attr<text_upright_e>("upright");
|
||||
if (upright_) upright = *upright_;
|
||||
|
||||
layout_defaults->from_xml(sym);
|
||||
|
||||
optional<expression_ptr> name_ = sym.get_opt_attr<expression_ptr>("name");
|
||||
if (name_)
|
||||
|
@ -213,42 +187,10 @@ void text_symbolizer_properties::to_xml(boost::property_tree::ptree &node,
|
|||
bool explicit_defaults,
|
||||
text_symbolizer_properties const& dfl) const
|
||||
{
|
||||
if (orientation)
|
||||
{
|
||||
std::string const& orientationstr = to_expression_string(*orientation);
|
||||
if (!dfl.orientation || orientationstr != to_expression_string(*(dfl.orientation)) || explicit_defaults) {
|
||||
set_attr(node, "orientation", orientationstr);
|
||||
}
|
||||
}
|
||||
|
||||
if (displacement.x != dfl.displacement.x || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "dx", displacement.x);
|
||||
}
|
||||
if (displacement.y != dfl.displacement.y || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "dy", displacement.y);
|
||||
}
|
||||
if (label_placement != dfl.label_placement || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "placement", label_placement);
|
||||
}
|
||||
if (valign != dfl.valign || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "vertical-alignment", valign);
|
||||
}
|
||||
if (text_ratio != dfl.text_ratio || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "text-ratio", text_ratio);
|
||||
}
|
||||
if (wrap_width != dfl.wrap_width || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "wrap-width", wrap_width);
|
||||
}
|
||||
if (wrap_before != dfl.wrap_before || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "wrap-before", wrap_before);
|
||||
}
|
||||
if (label_position_tolerance != dfl.label_position_tolerance || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "label-position-tolerance", label_position_tolerance);
|
||||
|
@ -269,22 +211,98 @@ void text_symbolizer_properties::to_xml(boost::property_tree::ptree &node,
|
|||
{
|
||||
set_attr(node, "minimum-path-length", minimum_path_length);
|
||||
}
|
||||
if (allow_overlap != dfl.allow_overlap || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "allow-overlap", allow_overlap);
|
||||
}
|
||||
if (avoid_edges != dfl.avoid_edges || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "avoid-edges", avoid_edges);
|
||||
}
|
||||
if (largest_bbox_only != dfl.largest_bbox_only|| explicit_defaults)
|
||||
if (allow_overlap != dfl.allow_overlap || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "largest-bbox_only", largest_bbox_only);
|
||||
set_attr(node, "allow-overlap", allow_overlap);
|
||||
}
|
||||
if (largest_bbox_only != dfl.largest_bbox_only || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "largest-bbox-only", largest_bbox_only);
|
||||
}
|
||||
if (max_char_angle_delta != dfl.max_char_angle_delta || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "max-char-angle-delta", max_char_angle_delta/(M_PI/180));
|
||||
}
|
||||
if (upright != dfl.upright || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "upright", upright);
|
||||
}
|
||||
|
||||
layout_defaults->to_xml(node, explicit_defaults, *(dfl.layout_defaults));
|
||||
format->to_xml(node, explicit_defaults, *(dfl.format));
|
||||
if (tree_) tree_->to_xml(node);
|
||||
}
|
||||
|
||||
|
||||
void text_symbolizer_properties::add_expressions(expression_set &output) const
|
||||
{
|
||||
if (layout_defaults) layout_defaults->add_expressions(output);
|
||||
if (tree_) tree_->add_expressions(output);
|
||||
}
|
||||
|
||||
void text_symbolizer_properties::set_old_style_expression(expression_ptr expr)
|
||||
{
|
||||
tree_ = std::make_shared<formatting::text_node>(expr);
|
||||
}
|
||||
|
||||
text_layout_properties::text_layout_properties() :
|
||||
orientation(),
|
||||
displacement(0.0,0.0),
|
||||
halign(H_AUTO),
|
||||
jalign(J_AUTO),
|
||||
valign(V_AUTO),
|
||||
text_ratio(0.0),
|
||||
wrap_width(0.0),
|
||||
wrap_before(false),
|
||||
rotate_displacement(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void text_layout_properties::from_xml(xml_node const &sym)
|
||||
{
|
||||
optional<double> dx = sym.get_opt_attr<double>("dx");
|
||||
if (dx) displacement.x = *dx;
|
||||
optional<double> dy = sym.get_opt_attr<double>("dy");
|
||||
if (dy) displacement.y = *dy;
|
||||
optional<vertical_alignment_e> valign_ = sym.get_opt_attr<vertical_alignment_e>("vertical-alignment");
|
||||
if (valign_) valign = *valign_;
|
||||
optional<horizontal_alignment_e> halign_ = sym.get_opt_attr<horizontal_alignment_e>("horizontal-alignment");
|
||||
if (halign_) halign = *halign_;
|
||||
optional<justify_alignment_e> jalign_ = sym.get_opt_attr<justify_alignment_e>("justify-alignment");
|
||||
if (jalign_) jalign = *jalign_;
|
||||
optional<double> text_ratio_ = sym.get_opt_attr<double>("text-ratio");
|
||||
if (text_ratio_) text_ratio = *text_ratio_;
|
||||
optional<double> wrap_width_ = sym.get_opt_attr<double>("wrap-width");
|
||||
if (wrap_width_) wrap_width = *wrap_width_;
|
||||
optional<boolean> wrap_before_ = sym.get_opt_attr<boolean>("wrap-before");
|
||||
if (wrap_before_) wrap_before = *wrap_before_;
|
||||
optional<boolean> rotate_displacement_ = sym.get_opt_attr<boolean>("rotate-displacement");
|
||||
if (rotate_displacement_) rotate_displacement = *rotate_displacement_;
|
||||
optional<expression_ptr> orientation_ = sym.get_opt_attr<expression_ptr>("orientation");
|
||||
if (orientation_) orientation = *orientation_;
|
||||
}
|
||||
|
||||
void text_layout_properties::to_xml(boost::property_tree::ptree &node,
|
||||
bool explicit_defaults,
|
||||
text_layout_properties const& dfl) const
|
||||
{
|
||||
if (displacement.x != dfl.displacement.x || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "dx", displacement.x);
|
||||
}
|
||||
if (displacement.y != dfl.displacement.y || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "dy", displacement.y);
|
||||
}
|
||||
if (valign != dfl.valign || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "vertical-alignment", valign);
|
||||
}
|
||||
if (halign != dfl.halign || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "horizontal-alignment", halign);
|
||||
|
@ -293,32 +311,34 @@ void text_symbolizer_properties::to_xml(boost::property_tree::ptree &node,
|
|||
{
|
||||
set_attr(node, "justify-alignment", jalign);
|
||||
}
|
||||
if (valign != dfl.valign || explicit_defaults)
|
||||
if (text_ratio != dfl.text_ratio || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "vertical-alignment", valign);
|
||||
set_attr(node, "text-ratio", text_ratio);
|
||||
}
|
||||
if (wrap_width != dfl.wrap_width || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "wrap-width", wrap_width);
|
||||
}
|
||||
if (wrap_before != dfl.wrap_before || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "wrap-before", wrap_before);
|
||||
}
|
||||
if (rotate_displacement != dfl.rotate_displacement || explicit_defaults)
|
||||
{
|
||||
set_attr(node, "rotate-displacement", rotate_displacement);
|
||||
}
|
||||
if (upright != dfl.upright || explicit_defaults)
|
||||
if (orientation)
|
||||
{
|
||||
set_attr(node, "upright", upright);
|
||||
std::string const& orientationstr = to_expression_string(*orientation);
|
||||
if (!dfl.orientation || orientationstr != to_expression_string(*(dfl.orientation)) || explicit_defaults) {
|
||||
set_attr(node, "orientation", orientationstr);
|
||||
}
|
||||
}
|
||||
format->to_xml(node, explicit_defaults, *(dfl.format));
|
||||
if (tree_) tree_->to_xml(node);
|
||||
}
|
||||
|
||||
|
||||
void text_symbolizer_properties::add_expressions(expression_set &output) const
|
||||
void text_layout_properties::add_expressions(expression_set &output) const
|
||||
{
|
||||
output.insert(orientation);
|
||||
if (tree_) tree_->add_expressions(output);
|
||||
}
|
||||
|
||||
void text_symbolizer_properties::set_old_style_expression(expression_ptr expr)
|
||||
{
|
||||
tree_ = std::make_shared<formatting::text_node>(expr);
|
||||
}
|
||||
|
||||
char_properties::char_properties() :
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
{
|
||||
"keys": [
|
||||
"",
|
||||
"9",
|
||||
"8",
|
||||
"4",
|
||||
"5",
|
||||
"7",
|
||||
"16",
|
||||
"6",
|
||||
"10",
|
||||
"2",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"11",
|
||||
"3",
|
||||
"15",
|
||||
"1"
|
||||
],
|
||||
"data": {},
|
||||
"grid": [
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" !! ",
|
||||
" !!! !!!! !!!!! ",
|
||||
" !! !! ! !!!! ! ! !!!!! ",
|
||||
" !!!! !! !!!!!! !! ! !! !!! !!!!! ! ",
|
||||
" !!!! !! !!!!!!! !!!! !! !!!!!!! !!!!!! ! ",
|
||||
" !!!!! !! !!!! !!!! !!!! !! !! !!!! !!!! !!!!!!! ! !! ",
|
||||
" !!!!! !! !!!! ! !!!! !!!!!! !!!!!! !!!!! !!!!!! !! !!! !! ",
|
||||
" !!!!! !! !! !!! !!!!!! !! ! !! !!!!!!!!! !!!!!!!!!!! !! !!!! ! ",
|
||||
" !!!!! !!!!!! !!!!!!!!!!! !!!!!! !! !!!!!! !!!! !!!!!!!! ! !! ! !!!! ",
|
||||
" !!! !! !!!! !!! !!!!!!! !!!!!!! !!! !!! ! !!! ! !!!!!!! !! !!! !!!! !! ",
|
||||
" !!!!!!!! !! !!!!! ! !!!! !!!!!! !!!!!!!!!!! !! !! !!!! !!!!!! !!!! ! ! ",
|
||||
" !! !!!!!!!! !! !! !!!!!!!!!!! !!! !!!!!!!! !! !!!!!!! !!!! !!!!!! ",
|
||||
" !! ! !!! !! !!!!!!!!!!! !!!!!!! !! !! !! !! !!!! !!!! !!!!!! ",
|
||||
" !! ! !! !! !! !! !!! !!! ! !! ! !!!! !! !!!!!!!!!! !!!!!!!!! !! ",
|
||||
" !! !!! !! !! !! ! !! !!!! !!!! !! !!!!!!!!!! !!!!!!!!!!! ",
|
||||
" !!!!!! !!!!! !! !!!!!!! ! !!!! !!!!!! !!!! !! !!!!!!! ",
|
||||
" !!!!!!!!!!!!! ! !!!!!! !! !!!!!! !!!!! !! !!! ",
|
||||
" ! !!!!! !! !!!!!! ! !! !!! !!! !! ! !! ",
|
||||
" !!!! ! !! !! !!!!!! !!!!!! !! ! ",
|
||||
" !!! !! !! !!!!!!!! !!! ! ",
|
||||
" !!!!!!! !!!!!!!! ",
|
||||
" ## !!!!!!!! !!!!!!!!! # $ ",
|
||||
" ### # # !!!!!!!! # !!!!!! ### $ ",
|
||||
" ##### ## # ### !!!!!!! ## ### ### !! #### $ ",
|
||||
" ###### ## ## #### !!! #### ## ## ##### #### # $$ $ ",
|
||||
" ######### ## ## #### ! #### ## ## ##### ######## #### ## # $$ $ ",
|
||||
" ######### ## ### ###### ###### # # ## ####### ####### ## ## #### ## $$ $ ",
|
||||
" ### ## #### ### # ######## ########### ## ### ##### ## ## ##### ### # ## #### ## $$ $$$ ",
|
||||
" ## ##### #### ######## ###### ###### ####### ### # #### ##### ## #### #### ## ## $$ $$$ $$ ",
|
||||
" ## ##### #### ## ## #### #### #### # # ######### ## #### ######## ## # $$ $$$ $$ ",
|
||||
" ## ##### ### # ## #### #### ## # #### ## ##### ## ###### ### $$ $$$ $$ ",
|
||||
" ## #### ### ## ## #### ####### ## #### # ## ######## ## ## #### $$ $$$$$$ ",
|
||||
" ## ##### #### ## ## ##### #### ## # ####### ###### ####### ## # ## $$ $$$$ $ ",
|
||||
" # ### ### ## ## ## #### ### ## ### ## ## #### ##### ##### # ## #### $$ $$$ $ ",
|
||||
" % # ### # ### ### ## #### ### ## ######## ## # #### #### ## #### $$ $$$ ",
|
||||
" % ## ## ####### ## ## ## ## ###### ## ####### # #### $$ $ ",
|
||||
" % ## ##### ## # ## ## ##### ## ## #### $$ $ ",
|
||||
" %%%% ## ## ## ## ## ## # # ## ## ## ### $$ $ ",
|
||||
" %%%% ## ##### ## ## ####### #### #### $ ",
|
||||
" %%%% ####### # ## # ## ### ### # $ ",
|
||||
" %%%%%%% ## ## ### # ####### # $ ",
|
||||
" %%%%%%%%% # # ####### # ## #### $ ",
|
||||
" %%%%%% %% ### # ##### ### ### $ ",
|
||||
" %%%%%%%%% #### ### ######## $ ",
|
||||
" %%%%%%%%% ####### &&&&& #### &&&&& $$ $ ",
|
||||
" %%%%%%% % &&&&& ### &&&&&& &&&&&&& &&& &&&& $$ $ ",
|
||||
" %%% %%%%% &&&&&& &&&&&&&&& &&&& & &&&&&& &&&&& $$ $$$ ",
|
||||
" %%%%%%% &&&&&&&& &&&&& &&&& &&&&& &&&&&&& &&&&&&&&& & $$ $$$ ",
|
||||
" %%%% &&&&&& &&&&&& &&&&& &&& && &&&&& &&& & & &&&&&&&&&&&& && $ $$$ $$ ",
|
||||
" %%%% &&&&&&&&&&& && &&&& && &&& && &&&&&& &&&&& & && && &&&&& & && $$ $$$ $$ ",
|
||||
" % % &&& &&&&&&& && &&&&& &&&&&& && && & &&&&&&&& & &&& &&&&&&&& & &&& $$ $$$ $$ ",
|
||||
" % &&&&&&&&&& && && &&&&&&&& & &&& &&&&&&& && &&&&& && &&&&&&&& &&&& $$ $$$$$$ ",
|
||||
" % &&&&&&& && & &&& & &&&& &&& &&&& && &&&&&&& &&&& && && &&&&& &&&&& & $$ $$$$$$ ",
|
||||
" % & &&&&&&&& &&&& & &&&&&&& &&&& & && &&&& & &&&& && && && & &&& &&&& & $$ $$$ ",
|
||||
" % & &&& &&&&&& && && &&& &&&&&& &&&&& && & &&&&&&&&&&& && &&&&&&&&& && $$ $$$ ",
|
||||
" % & && & &&&&&&&&& && & &&&&&&&& & & &&& &&&&& &&&&&&& && && $$ $ ",
|
||||
" % & &&&&&&& && &&&&&&& &&&& &&&&& & &&& &&&&&&& && $$ $ ",
|
||||
" % &&&& & & && &&&&&& &&& &&&&&&&&&& &&&&& && $ ",
|
||||
" % %% &&&&&&&&&& &&&& &&&& &&&&& & &&&&&&& $ ",
|
||||
" % %% &&&&& &&&&&&& &&&&&&& & && &&& $ ",
|
||||
" %%% %% &&&&&&& &&&&&&& &&& &&& &&&& $ ",
|
||||
" %%% %% &&& &&& &&&&& & &&&&& &&& $ ",
|
||||
" %%%%%% %% &&&&& &&& && $ ",
|
||||
" %%%%%% %% &&& & ''''''''' $$ $ ",
|
||||
" %% %%% %% '''''''' ''''''' $$ $ ",
|
||||
" %% %%% %% ''''''''' ' $$ $ ",
|
||||
" %% %%% % (( ((( ''''' ' $$ $$$ ",
|
||||
" %%% %% ( ( (( ((((( (((((( ''''' ' $ $$$ $$ ",
|
||||
" % %% ((( ((((( ((((((( (((((( '''''''''''''''''''''''' $$ $$$ $$ ",
|
||||
" % %% ((((((( ((((((( ((((( ( (((( ((( $$ $$$ $$ ",
|
||||
" % %% (((((( ( (((( (( (((((((( ((((((( ''''''''''''' $$ $$$$$$ ",
|
||||
" % ((((((( (((((((( ( (((( ((((( ((( (((((((( '''''''' '''' $$ $$$$$$ ",
|
||||
" % ( ((((( ((((( ((( ((((((( ((((( (( (( ( (( '''''''' '''' $$ $$$ ",
|
||||
" % (( ((( (( ( ((( (( (( (( ((((( (( ( (( (((((( (( ((( $$ $$$ ",
|
||||
" % (( (((( (( ((( (( ((((((( ( (( (( ((( (((( (( (( (( (((((((( (( ((( ( $$ $ ",
|
||||
" % (( (((((((( (( ((( (( ((( (((( (( (((( ( (((((( (( (( ((( (( (( (((( ( ((((((( $$ $ ",
|
||||
" % (( ((((( (( (((( ((( (( ((((( (( ((((((( (( ((((( ( (((((( (( (((( ( ((((((( $ ",
|
||||
" % ( ((((( (((((( ((((((( ( ((((( ( (((((( (( (((( ( ((((((( (( (((( ( (((((( $ ",
|
||||
" % %% ( (((( ((( ( ((((((( ( (((( ( ((((( (( ((( (( ((( (( ((( (((((((((( (( $ ",
|
||||
" % %% ( ((( ((( ((((( (( (( ((( (((( (( (((((((((( ( ((( (( ((( (( $ ",
|
||||
" %%% %% ( (((((((( (( (( (( (((( ( ((( (( ((( (( ((( (( ( ((( $ ",
|
||||
" %%% %% ((( ((( (( ((( (( (( (( ((( ((( (( ((((( ((((( $ ",
|
||||
" %%%%%% %% (((( (( ((( ((( ((((( ((((( (( (((((( $$ $ ",
|
||||
" %%%%%% %% ( (( ((( ((((( ((((((((( ))) ((( (((( $$ $ ",
|
||||
" %% %%% %% ((((( ** + (((((((( ((( (((( ))))))))))))) (((((( $$ $ ",
|
||||
" %% %% %% ((( * ** + ((((((( ((( )))))))) )))) ))))))) $$ $$$ ",
|
||||
" %% %%% % **** ** + ))))))))) ) ))))))))) $$ $$$ $ ",
|
||||
" %%% %% **** ** + , ) )))))))))))))))))))) ))) )) $$ $$$ $$ ",
|
||||
" %%% %% ****** * + , ------ --- )))))))) )))))))) )))) $$ $$$ $$ ",
|
||||
" % %% **** ****** ** + , -------- ---- )))))))) ))))))))))) $$ $$$$$$ ",
|
||||
" % %% ****** ****** + , -- ------ ---- )) )))))))))))) $ $$$$ $ ",
|
||||
" % * ** * **** ++++ , ---------------------------- ))))) )) )))) ) $$ $$$$$ ",
|
||||
" % ** **** + ++ , ---- - - ))))) ))) )) )) $$ $$$ ",
|
||||
" % ** **** + ++ , -------- ))))) ) $$ $ ",
|
||||
" % * ***** +++++++ , -------- ) ) $$ $ ",
|
||||
" % ** **** ++++++ , . ----- .. . .. ..... )) $$ $ ",
|
||||
" % ** **** ++++ ++++ , . ..........----- ....... ..... ) $ ",
|
||||
" % * ** +++++++++ , ,, ........ .... ............. ) $ ",
|
||||
" % %% ** ++++++ ++ , , ,,, ...... ................................ ) $ ",
|
||||
" % %% ** ++ +++ ++ ,, , ,, ......... .... . . ) $ ",
|
||||
" %%%% * * ++ +++++++,, ,,, ,, .. ......... ........ ) )) $ ",
|
||||
" %% %%% **** ** ++ +++,,,,,,, , . . ....... ........ ) )) $ ",
|
||||
" % %%%%%% **** ** ///// +++,,,,, ,,,, .. .... ..... )) ) )) $$ $ ",
|
||||
" %%%%% %%% ******* * ////////// ++++,,,, , ,, . ...... ..... )) ))) )) $$ $ ",
|
||||
" %%%%% %%%% **** *** ** ** /////////// + ,,,,,,,,,, . ...... ))))))) $$ $$$ ",
|
||||
" %%%%% %%% ******* ** *** //// ////// / + ,, , ,, . 0 0 0 0 )))) )))) $$ $$$ ",
|
||||
" %%%%%%%%% * *** * ***** // ////// ////// /// ++ ,, , ,, . 00000000 ))))) ) )) $ $$$ $$ ",
|
||||
" %% %% %%%% ** **** ///////// ///////// + ,,,, . 00000000 ))))) )))) $$ $$$ $$ ",
|
||||
" %% %%%% ** *** ////////// ///// + ,,,, . . 00000 ))))) )))) $$ $$$$$$ ",
|
||||
" %%% * ***** / /////// // /// + ,,,, ... 00000 ))) )))) $$$ $$$$$$ ",
|
||||
" %%% ** **** // /////// //// // + , ... 00000 ) ))) $$ $$$$$$ ",
|
||||
" %%% ******* // // /// //// + , ..... . 00000000000000000000000000000 ) )) $$ $$$ ",
|
||||
" % * *** // /////// / , .. .... 0 0 00 ) )) $$$ $$$ ",
|
||||
" % ** * // /////// /// , . ... .. 00000000 0000 ) $$ $ ",
|
||||
" % * // // ////// / // , .. ... .. 00000000 0000 ) $$ $ ",
|
||||
" % /// ////// //// , .. ... .. )))))))) )) )) $ ",
|
||||
" % //// // / //// , .. ...... ))))))))) )))))))) ) $ ",
|
||||
" % /////// / , .. ...... ))))))) )))))))) ) $ ",
|
||||
" % / /// / .. ... ))))) )))) )) $ ",
|
||||
" %%%% // /// // // .. ... ))))) )))))) ) $ ",
|
||||
" %%%% // /// // // .... ))))))))))))) ))))) ) $ ",
|
||||
" %%%%%% /// ///// / .... ))))))))))))))))))))))))))))) $$$ ",
|
||||
" %%%%%%% ///////// / . )))))))))) )) $$$ ",
|
||||
" %%%%%%%% ///////// // . )))))))) )))) )))))))) )))) $$$ ",
|
||||
" %%%% %%%% /////// / . )))) )))) )))))))) )))) $$$ $$ ",
|
||||
" %%%% %%% // / / .. .. $$$ $$ $$ ",
|
||||
" %%%%%%%%% // / / . ... . $$$$$$$$$ ",
|
||||
" %%%% % % / / . ....... ........ $$$ $$$$$ ",
|
||||
" %%%%%%% / / . ...... ........ $$$$ $$$$$ ",
|
||||
" %%% / / .. .. ..... $$$$$$$$$ ",
|
||||
" %%% / / .. ..... ..... $$$ $$ ",
|
||||
" %%% / / .. ... ..... $$$ $$ ",
|
||||
" % // / .. ..................................... $$$$ ",
|
||||
" % // / ..... . . .. $$$ ",
|
||||
" % / / ............ ............. $ ",
|
||||
" % / / ..... .... ............. $ ",
|
||||
" // // $ ",
|
||||
" / / $ ",
|
||||
" / / ",
|
||||
" / // ",
|
||||
" // // 1 1 1 ",
|
||||
" / // 11111111 111111111 ",
|
||||
" / // 11111111 111111111 ",
|
||||
" / // 1 11 11111 ",
|
||||
" /// // 11111 11111 ",
|
||||
" /////// // 11111 111 1 ",
|
||||
" /////// // 11111111111111111111111111111111111111111111111 ",
|
||||
" /// 111 1 1 1111 ",
|
||||
" 1111111111111 11111111 1111 ",
|
||||
" 11111111 1111 11111111 1111 ",
|
||||
" 1 1 ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
]
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
{
|
||||
"keys": [
|
||||
"",
|
||||
"1"
|
||||
],
|
||||
"data": {},
|
||||
"grid": [
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ! ",
|
||||
" ! ",
|
||||
" ! !!!!! ",
|
||||
" !!! ! ",
|
||||
" !!!!!!!! ! ! ! ",
|
||||
" ! !! ! ! ",
|
||||
" !! ! !! ! ",
|
||||
" !! !!! !! ! ",
|
||||
" ! ! !!! ! ! ",
|
||||
" ! ! ! ! !! ",
|
||||
" ! ! ! ! ",
|
||||
" !! ! ! ! ",
|
||||
" ! ! ! !! ! !! ",
|
||||
" ! !!! !! ! ! ! ",
|
||||
" ! ! !! ! ! !!! ",
|
||||
" ! !! !!! !! ! ",
|
||||
" ! !!! ! ! ! ! ",
|
||||
" ! ! ! !!!! ! ! !! ",
|
||||
" ! !! ! ! !! ! ",
|
||||
" ! ! ! ! ! !! ",
|
||||
" ! !! ! ! !! ",
|
||||
" !! ! ! ! ! ! !!! ",
|
||||
" ! !! !!! !! ! !!! ",
|
||||
" ! ! ! ! ! ! ! !! ",
|
||||
" !! ! ! !!! ! ! ! ",
|
||||
" ! !! !! ! !!! ! ",
|
||||
" !!! ! !!! !! ! ! ! ",
|
||||
" !! ! ! ! !!! ",
|
||||
" ! ! ! ! ! ",
|
||||
" !! ! ! !! ",
|
||||
" !! ! ! ",
|
||||
" ! ! ! !! ! ",
|
||||
" ! ! ! ! ",
|
||||
" !!! !! !! ! ",
|
||||
" !!!! ! !! !!! ",
|
||||
" !! ! ! ! !! ! ",
|
||||
" ! !!! !!!! !!!! ",
|
||||
" !! ! ! ! !! ! ",
|
||||
" !!! ! !!! !! ! ",
|
||||
" ! ! ! !! ! ",
|
||||
" !! ! !! ! ",
|
||||
" ! ! ! ! ",
|
||||
" ! ! ! ",
|
||||
" ! !!!!! ! ",
|
||||
" ! ! ! ! ",
|
||||
" ! ! !! ! ",
|
||||
" ! ! !! ! ",
|
||||
" ! ! ! ",
|
||||
" ! ! ! ",
|
||||
" ! !!! ! ! ",
|
||||
" ! ! ! !!!!! ",
|
||||
" ! ! !!!!! ! !! ",
|
||||
" ! ! !! ! ! !!! ",
|
||||
" ! ! ! ! ! ! !! ",
|
||||
" ! !!! !!! ! ! !! ",
|
||||
" ! ! ! ! !! ",
|
||||
" !!!! ! ! ! ! ",
|
||||
" ! !!! !! ! !!!! ",
|
||||
" ! !! !! ! ! ",
|
||||
" ! ! ! ! ! ",
|
||||
" ! !! !! ! ! !! ",
|
||||
" ! ! !!!! ! ! ! ! ",
|
||||
" ! !! !! !! ! ! ",
|
||||
" ! !! !!! ! !! ! ",
|
||||
" ! !!! !!! ! ! ! ",
|
||||
" ! ! !! ! ! ",
|
||||
" !!!! ! !!!! ! ",
|
||||
" !!!! !! ! !! ! ",
|
||||
" !! ! !! ! ! ",
|
||||
" ! ! ! !! ! ",
|
||||
" !! ! ! ! ! ",
|
||||
" ! ! !! !!!! ",
|
||||
" !!! ! ! ",
|
||||
" ! ! !! ! ! ",
|
||||
" ! ! !! ! ! ! ",
|
||||
" !! ! ! !!! ! !! ",
|
||||
" !!! ! ! !!!!! ",
|
||||
" !!!! !!! ! !! ! ",
|
||||
" !! ! ! !! !!! ",
|
||||
" !!! ! ! !! ! ",
|
||||
" !! ! ! !! ",
|
||||
" ! ! !! ! ",
|
||||
" ! ! ! ! ",
|
||||
" ! !!!! ! ",
|
||||
" ! ! !! !! ",
|
||||
" ! ! ! ! ! ",
|
||||
" ! !! ! ",
|
||||
" ! ! ! ",
|
||||
" ! ! ! ",
|
||||
" ! !! ! ! ",
|
||||
" ! ! ! ! ! ",
|
||||
" ! !!! ! ! ! ! ",
|
||||
" ! ! ! !! ! ! ! ",
|
||||
" ! !! !!! ! ! ! ",
|
||||
" !!! !!! ! ! !! ",
|
||||
" ! !! !! ! ! ! ! ",
|
||||
" ! !! ! ! ! !!! ",
|
||||
" ! !!! ! ! ! !!! ",
|
||||
" ! !!! ! ! ! ! !! ",
|
||||
" ! ! !! ! ! ",
|
||||
" ! ! ! ! ! !! ",
|
||||
" !! !! !!!! ! !! ! ",
|
||||
" ! ! ! ! !! ",
|
||||
" ! !! !!! ! ! !! ",
|
||||
" ! ! ! ! !!! ",
|
||||
" ! !!! ! ! ! ",
|
||||
" ! ! ! !!!! ",
|
||||
" !!!! ! !!!! ! ",
|
||||
" !! !! ! !! ! ",
|
||||
" ! ! ! ! ! ",
|
||||
" !! ! ! !! ! ",
|
||||
" ! ! ! ! ! ",
|
||||
" ! ! !!! !!! ",
|
||||
" !!! ! ! !! ! ",
|
||||
" ! ! !!! ! ! ",
|
||||
" !!! ! !! ! ! ",
|
||||
" !!!! ! ! !!! ",
|
||||
" !!!! !!!! ! ! ",
|
||||
" !! ! !!! ! !! ! ",
|
||||
" !! ! ! ! !! ! ",
|
||||
" ! ! !! ! ! ",
|
||||
" ! ! !! !!! ",
|
||||
" !! ! !! ! ",
|
||||
" ! ! !! ! ",
|
||||
" ! ! !!! ! ",
|
||||
" ! ! ! !! ",
|
||||
" ! !! ! ",
|
||||
" ! ! ! ",
|
||||
" ! !!! ! ! ",
|
||||
" ! ! !! !! ",
|
||||
" ! !!! ! ! ",
|
||||
" ! !!! ! ! ",
|
||||
" ! ! ! ! ! ! ",
|
||||
" ! ! !!! ! ! !! ",
|
||||
" ! !! ! !! ! ",
|
||||
" ! ! ! ! ! ",
|
||||
" ! ! ! ! ! ! ! ",
|
||||
" ! ! ! ! ! ! !!!! ",
|
||||
" ! !!!! !! ! ! ! ! ",
|
||||
" ! ! ! !! !! ! ! ",
|
||||
" ! !! !!!! ! !! ",
|
||||
" ! ! ! ! ! ! ! ",
|
||||
" ! ! ! ! ! ! ",
|
||||
" ! ! ! ! ! !! ",
|
||||
" ! ! ! ! ! ",
|
||||
" ! ! ! ! !! ",
|
||||
" ! ! ! !! ! !! ",
|
||||
" ! !!! ! !! !! ! ! ",
|
||||
" ! !! !! ! ! ! ",
|
||||
" ! ! !! ! !! ! ",
|
||||
" !!! ! ! !!!!! !!! ",
|
||||
" !! ! ! !! ! ! ",
|
||||
" ! !!!!!! !!! ",
|
||||
" !! ! ! !! ! ! ",
|
||||
" !! !!! ! ! ",
|
||||
" !! !! ! ! !! ",
|
||||
" ! !! ! !!!! ",
|
||||
" ! ! ! ! ! ! ! ",
|
||||
" ! ! ! ! ! ",
|
||||
" ! !! !!!!! !! ! ",
|
||||
" ! !!! ! !!! ! ! ",
|
||||
" !!! ! ! ! ! ! ",
|
||||
" !!!! !! ! ",
|
||||
" !! ! ! ! ",
|
||||
" !! ! ! ",
|
||||
" ! ! !! ",
|
||||
" ! !! ! ! ",
|
||||
" ! !!! !! ! ",
|
||||
" ! !!! !! !! ",
|
||||
" ! !! ! !! !! ",
|
||||
" ! !!!! !!!!!! ",
|
||||
" ! !!! ",
|
||||
" !!!! !!! ",
|
||||
" !! ! ",
|
||||
" !! ! ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
]
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
{
|
||||
"keys": [
|
||||
"",
|
||||
"8",
|
||||
"7",
|
||||
"6",
|
||||
"5",
|
||||
"9",
|
||||
"4",
|
||||
"2",
|
||||
"1",
|
||||
"3"
|
||||
],
|
||||
"data": {},
|
||||
"grid": [
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! ",
|
||||
" !!!!!!!!! !!!!!!!!! !!!!!!!!! !!!!!!!!! !!!!!!!!! !!!!!!!!! !!!!!!!!! !!!!!!!!! !!!!!!!!! !!!!!!!!! !!!!!!!!! !!!!!!!!! ",
|
||||
" !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! ",
|
||||
" !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! ",
|
||||
" ",
|
||||
" !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! !!!!! ",
|
||||
" !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ######### ######### ######### ######### ######### ######### ######### ######### ######### ######### ######### ######### ",
|
||||
" ######### ######### ######### ######### ######### ######### ######### ######### ######### ######### ######### ######### ",
|
||||
" ######### ######### ######### ######### ######### ######### ######### ######### ######### ######### ######### ######### ",
|
||||
" ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ",
|
||||
" #################################################################################################################################################################################### ",
|
||||
" ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ",
|
||||
" ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ",
|
||||
" #### #### #### #### #### #### #### #### #### #### #### #### ",
|
||||
" #### #### #### #### #### #### #### #### #### #### #### #### ",
|
||||
" # ## # ## # ## # ## # ## # ## # ## # ## # ## # ## # ## # ## ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ ",
|
||||
" $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ ",
|
||||
" $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ $$$$$$ $$ ",
|
||||
" $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ ",
|
||||
" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ",
|
||||
" $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ ",
|
||||
" $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ ",
|
||||
" $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ ",
|
||||
" $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ ",
|
||||
" $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ $$$$ ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% ",
|
||||
" %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% %%%%%%%% ",
|
||||
" %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% ",
|
||||
" %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% ",
|
||||
" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ",
|
||||
" %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% %%%%%% ",
|
||||
" ",
|
||||
" %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% ",
|
||||
" %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ''''''' ' '''''''' (((((((( ",
|
||||
" '' '''''' '' ''''' (((((((( ( ((((((((( ",
|
||||
" )))) )))) ''''''' ' '''''''' (((((((( ((( ((( (((((( (( ",
|
||||
" )))) )))) ) ))))))))) '''''' '''''' ((((((((( (((((((( (( ",
|
||||
" ))))))))) )))))) ))))))))) '''''''''''''''''''''''''''''''''''''' (((((( ((((((( ",
|
||||
" )))))))) )))))))))) '''''' '''''' (((((( ((((( ",
|
||||
" )))))) ))))))) '''''' '''''' (((((( ((((( ",
|
||||
" ))))) )))))) ''''' ''''' (((( ((((( ",
|
||||
" ))))) )))))) '''' '' ' (( ( (((( ",
|
||||
" )))) )))))) '''' '''' ((((( (((( ",
|
||||
" )))) )))) ( ((((( ",
|
||||
" )))) )) ) (( ( ",
|
||||
" ) ) ))) ( ( ",
|
||||
" ) ) ( ( ",
|
||||
" )) ) ( ( ",
|
||||
" ) ) ( (( ",
|
||||
" ) ) ( ( ",
|
||||
" ) ) ( ( ",
|
||||
" ) )) ((((((((( (((( (((( ",
|
||||
" ) ) ((((((( ( (((( (((( ",
|
||||
" ))))))))) )))))))) (((((( ((((((((( ",
|
||||
" ))))))))) )))))))) (((((( ((((( ",
|
||||
" ))))) )))))))) (((((( ((((( ",
|
||||
" ))))) )))))) ((((((( ((((( ",
|
||||
" ))))) )))))) ******** ******** (( (((((((( ",
|
||||
" )))))) )))))) ******* ******** ((((( (( ((( (((( ",
|
||||
" ))) )))))))) ****** ****** (((( (( (((( ",
|
||||
" )))) ))) ))) )))) ****** ****** (((( ",
|
||||
" )))) )) )) ) ************************************** ",
|
||||
" )))) ****** ****** ",
|
||||
" ****** ****** ",
|
||||
" ***** **** ",
|
||||
" **** **** ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
]
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
{
|
||||
"keys": [
|
||||
"",
|
||||
"2",
|
||||
"3",
|
||||
"5",
|
||||
"6",
|
||||
"4",
|
||||
"1"
|
||||
],
|
||||
"data": {},
|
||||
"grid": [
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ! # ",
|
||||
" !! ## ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" $ ",
|
||||
" $ ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" % ",
|
||||
" %% ",
|
||||
" % ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" & ' ",
|
||||
" && '' ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
]
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
{
|
||||
"keys": [
|
||||
"",
|
||||
"1"
|
||||
],
|
||||
"data": {},
|
||||
"grid": [
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ! ",
|
||||
" !!! ",
|
||||
" ! !! ",
|
||||
" ! ! !!! ",
|
||||
" !! ! ! ",
|
||||
" !!! !!! ",
|
||||
" ! ! !!! ",
|
||||
" ! ! !! ! ",
|
||||
" ! ! !! !!! ",
|
||||
" !! !!! !!! ",
|
||||
" ! ! !!! ! ! ",
|
||||
" !! ! ! !!!! !! ! ",
|
||||
" ! ! !! !!! !!! !! ",
|
||||
" !! !!! ! ! !! ",
|
||||
" !! !! !! ! ! ",
|
||||
" !! !!!! !!! !! ",
|
||||
" !! ! !! !! !!! ! ! ! ",
|
||||
" !! !!!!!!!!!!! !!!!! !!! ! !!!! ! ! !!! ",
|
||||
" !! ! !! !!!!!! !!! ! !! !!! !! ! ",
|
||||
" ! !!! !! !! ! ",
|
||||
" ! !! ! ! !!! ",
|
||||
" !! !!! ! !! !!! ! ",
|
||||
" !! !!!!!!! !!!!! ! !! !!! !!! ",
|
||||
" !!!!!!!!!! !!! !!!! ! ! ! !! ",
|
||||
" !!! !!! ! ! ",
|
||||
" ! !!! !! ",
|
||||
" ! !!! !!! ",
|
||||
" ! !!!! ",
|
||||
" !!! ",
|
||||
" ! ! ",
|
||||
" ! ",
|
||||
" ",
|
||||
" ",
|
||||
" ! !! ! !! ! ",
|
||||
" !!!!!!!!!!!!!!!!!! !!!!!!!! !!!!!!!! !!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!! !!!!!!!! !!!!!!!! !!!!!!!!! ",
|
||||
" ! !!! ! ! ! !!! ! ! ! ! ! !! ",
|
||||
" ! ! !!! !! ! !! ! ",
|
||||
" ! !!!!!!!! !!!!!!!!!!!!!!!!! !!!!!!!!! ",
|
||||
" !!!!!!!!!! !!!!!!!!!!!!!!!!! !!!!!!!!! ",
|
||||
" !! ! ! ! ! ! ",
|
||||
" !!!!!!!!!!!! !!!!!!! ",
|
||||
" !!!!!!!!!!!! !!!!!!! ",
|
||||
" ! ! ! ! ! !! ! ",
|
||||
" ! ! ",
|
||||
" !!!!!!!!! ",
|
||||
" !!!!!!!!!! ",
|
||||
" ! ! ! ",
|
||||
" !!!!!!! ",
|
||||
" !!!!!! ",
|
||||
" !! ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 21 KiB |
34
tests/visual_tests/styles/lines-multi-layout-1.xml
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map>
|
||||
<!-- Upright test -->
|
||||
<Map background-color="white" srs="+proj=latlong +datum=WGS84">
|
||||
|
||||
<Layer name="layer" srs="+proj=latlong +datum=WGS84">
|
||||
<StyleName>lines</StyleName>
|
||||
<StyleName>text</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type">csv</Parameter>
|
||||
<Parameter name="file">../data/lines2.csv</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
<Style name="lines">
|
||||
<Rule>
|
||||
<LineSymbolizer stroke-width="3" stroke="green"/>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
<Style name="text">
|
||||
<Rule>
|
||||
<TextSymbolizer face-name="DejaVu Sans Book" size="10" placement="line" spacing="25" fill="#00ff00" halo-radius="1" halo-fill="rgba(255,255,255,0.6)" max-char-angle-delta="90">
|
||||
<Layout dy="-3" vertical-alignment="top" wrap-width="33" wrap-before="true">
|
||||
<Format fill="#ff0000">"District One"</Format>
|
||||
</Layout>
|
||||
<Layout dy="5" vertical-alignment="bottom">
|
||||
<Format fill="#0000ff">"District Two"</Format>
|
||||
</Layout>
|
||||
</TextSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
</Map>
|
33
tests/visual_tests/styles/lines-multi-layout-2.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map>
|
||||
<!-- Upright test -->
|
||||
<Map background-color="white" srs="+proj=latlong +datum=WGS84">
|
||||
|
||||
<Layer name="layer" srs="+proj=latlong +datum=WGS84">
|
||||
<StyleName>lines</StyleName>
|
||||
<StyleName>text</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type">csv</Parameter>
|
||||
<Parameter name="inline">
|
||||
wkt,nr
|
||||
"LINESTRING(1.000 1.000, 0.958 0.646, 0.917 0.331, 0.875 0.055, 0.833 -0.185, 0.792 -0.390, 0.750 -0.562, 0.708 -0.703, 0.667 -0.815, 0.625 -0.898, 0.583 -0.956, 0.542 -0.989, 0.500 -1.000, 0.458 -0.990, 0.417 -0.961, 0.375 -0.914, 0.333 -0.852, 0.292 -0.776, 0.250 -0.688, 0.208 -0.589, 0.167 -0.481, 0.125 -0.367, 0.083 -0.248, 0.042 -0.125, 0.000 0.000, -0.042 0.125, -0.083 0.248, -0.125 0.367, -0.167 0.481, -0.208 0.589, -0.250 0.688, -0.292 0.776, -0.333 0.852, -0.375 0.914, -0.417 0.961, -0.458 0.990, -0.500 1.000, -0.542 0.989, -0.583 0.956, -0.625 0.898, -0.667 0.815, -0.708 0.703, -0.750 0.562, -0.792 0.390, -0.833 0.185, -0.875 -0.055, -0.917 -0.331, -0.958 -0.646, -1.000 -1.000)",1
|
||||
</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
<Style name="lines">
|
||||
<Rule>
|
||||
<LineSymbolizer stroke-width="3" stroke="green"/>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
<Style name="text">
|
||||
<Rule>
|
||||
<TextSymbolizer face-name="DejaVu Sans Book" size="14" placement="line" spacing="40" upright="left" max-char-angle-delta="45">
|
||||
<Layout dy="-5" horizontal-alignment="left">"Align Left"</Layout>
|
||||
<Layout dy="5" horizontal-alignment="right">"Align Right"</Layout>
|
||||
</TextSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
</Map>
|
33
tests/visual_tests/styles/lines-multi-layout-shield.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map>
|
||||
<!-- Upright test -->
|
||||
<Map background-color="white" srs="+proj=latlong +datum=WGS84">
|
||||
|
||||
<Layer name="layer" srs="+proj=latlong +datum=WGS84">
|
||||
<StyleName>lines</StyleName>
|
||||
<StyleName>text</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type">csv</Parameter>
|
||||
<Parameter name="file">../data/lines.csv</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
<Style name="lines">
|
||||
<Rule>
|
||||
<LineSymbolizer stroke-width="3" stroke="red"/>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
<Style name="text">
|
||||
<Rule>
|
||||
<ShieldSymbolizer placement="line" spacing="60" minimum-distance="10" label-position-tolerance="0.5" face-name="DejaVu Sans Bold" size="14" fill="#ffffff" file="../../data/svg/rect.svg">
|
||||
[nr]
|
||||
<Format size="10" face-name="DejaVu Sans Book" fill="#000000" halo-fill="rgba(255,255,255,0.6)" halo-radius="1.5">
|
||||
<Layout dy="-10">"SOUTH"</Layout>
|
||||
<Layout dy="10">"ALT"</Layout>
|
||||
</Format>
|
||||
</ShieldSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
</Map>
|
65
tests/visual_tests/styles/text-multi-layout-1.xml
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map>
|
||||
<Map background-color="green" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" minimum-version="2.0.0">
|
||||
|
||||
<Layer name="obstacle" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
||||
<StyleName>obstacle</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type">csv</Parameter>
|
||||
<Parameter name="inline">
|
||||
lat,long,nr
|
||||
-0.5,0.5,0
|
||||
0.5,-0.5,1
|
||||
0.5,0.5,2
|
||||
-0.5,-0.5,3
|
||||
0.08,0,4
|
||||
-0.08,0,5
|
||||
</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
<Style name="obstacle">
|
||||
<Rule>
|
||||
<PointSymbolizer file="../../data/svg/crosshair16x16.svg" transform="scale(0.5)"/>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
<Layer name="layer1" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
||||
<StyleName>points</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type">csv</Parameter>
|
||||
<Parameter name="inline">
|
||||
lat,long,nr,ref
|
||||
-0.45,-0.45,0,first
|
||||
0.45,-0.45,1,second
|
||||
0.45,0.45,2,third
|
||||
-0.45,0.45,3,fourth
|
||||
0,0,4,fifth
|
||||
</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
<Style name="points">
|
||||
<Rule>
|
||||
<PointSymbolizer allow-overlap="true" ignore-placement="true" file="../../data/raster/white-alpha.png"/>
|
||||
<TextSymbolizer face-name="DejaVu Sans Book" placement="point" placement-type="list" size="16" dx="-4" dy="-8">
|
||||
"test "+[nr]
|
||||
<Layout dx="0" dy="8" horizontal-alignment="right">
|
||||
<Format fill="red">[ref]</Format>
|
||||
</Layout>
|
||||
<Placement size="14" dy="8">
|
||||
"test "+[nr]
|
||||
<Format fill="blue">
|
||||
<Layout dx="0" dy="-8" horizontal-alignment="right">[ref]</Layout>
|
||||
</Format>
|
||||
</Placement>
|
||||
<Placement dx="0" dy="0">
|
||||
"test "+[nr]
|
||||
<Format fill="yellow">" ("+[ref]+")"</Format>
|
||||
</Placement>
|
||||
</TextSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
</Map>
|
||||
|
48
tests/visual_tests/styles/text-multi-layout-2.xml
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map>
|
||||
<Map background-color="green" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" minimum-version="2.0.0">
|
||||
|
||||
<Layer name="layer1" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
||||
<StyleName>points</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type">csv</Parameter>
|
||||
<Parameter name="inline">
|
||||
lat,long
|
||||
0,0
|
||||
</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
<Style name="points">
|
||||
<Rule>
|
||||
<PointSymbolizer allow-overlap="true" ignore-placement="true" file="../../data/raster/white-alpha.png"/>
|
||||
<TextSymbolizer face-name="DejaVu Sans Bold" size="16" wrap-width="60" placement="point" dx="-15" dy="-10">
|
||||
"Symbolizer Base Text"
|
||||
<Format face-name="DejaVu Sans Book" size="12">
|
||||
<Layout orientation="45" dx="25">
|
||||
"Rotated Layout with "
|
||||
<Format fill="blue">
|
||||
"Blue Format Child Node"
|
||||
<Layout vertical-alignment="top" rotate-displacement="true" dy="-5">
|
||||
"Rotated child layout with rotate-displacement"
|
||||
</Layout>
|
||||
</Format>
|
||||
</Layout>
|
||||
<Layout wrap-width="100" wrap-before="true" dy="30">
|
||||
<Format halo-radius="1.5">
|
||||
"South Offset Layout"
|
||||
<Layout dx="30" horizontal-alignment="middle" justify-alignment="center">
|
||||
<Format halo-fill="turquoise">"South offset child layout, centered"</Format>
|
||||
</Layout>
|
||||
<Layout dx="75" wrap-width="20" horizontal-alignment="right" justify-alignment="right">
|
||||
<Format face-name="DejaVu Sans Oblique">"South offset child layout, right"</Format>
|
||||
</Layout>
|
||||
</Format>
|
||||
</Layout>
|
||||
</Format>
|
||||
</TextSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
</Map>
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import mapnik
|
||||
mapnik.logger.set_severity(mapnik.severity_type.None)
|
||||
#mapnik.logger.set_severity(mapnik.severity_type.Debug)
|
||||
|
||||
import shutil
|
||||
import sys
|
||||
|
@ -96,6 +97,9 @@ files = {
|
|||
'lines-5': {'sizes': sizes_few_square,'bbox':default_text_box},
|
||||
'lines-6': {'sizes': sizes_few_square,'bbox':default_text_box},
|
||||
'lines-7': {'sizes': sizes_few_square,'bbox':mapnik.Box2d(-1.2, -1.2, 1.2, 1.2)},
|
||||
'lines-multi-layout-1': {'sizes': [(800,800)],'bbox':default_text_box},
|
||||
'lines-multi-layout-2': {'sizes': [(800,800)],'bbox':mapnik.Box2d(-1.2, -1.2, 1.2, 1.2)},
|
||||
'lines-multi-layout-shield': {'sizes': [(800,800)],'bbox':default_text_box},
|
||||
'lines-shield': {'sizes': sizes_few_square,'bbox':default_text_box},
|
||||
'collision': {'sizes':[(600,400)]},
|
||||
'shield-on-polygon': {'sizes':[(600,400)]},
|
||||
|
@ -156,6 +160,8 @@ files = {
|
|||
'text-halign': {'sizes': [(800,800)], 'bbox': default_text_box},
|
||||
'text-malayalam': {'sizes': [(800, 100)], 'bbox': default_text_box},
|
||||
'text-bengali': {'sizes': [(800, 100)], 'bbox': default_text_box},
|
||||
'text-multi-layout-1': {'sizes': [(512,512)], 'bbox':mapnik.Box2d(-1, -1, 1, 1)},
|
||||
'text-multi-layout-2': {'sizes': [(512,512)], 'bbox':mapnik.Box2d(-1, -1, 1, 1)},
|
||||
'line-pattern-symbolizer': {'sizes':[(900, 250)],'bbox': mapnik.Box2d(-5.192, 50.189, -5.174, 50.195)},
|
||||
'tiff-alpha-gdal': {'sizes':[(600,400)]},
|
||||
'tiff-alpha-broken-assoc-alpha-gdal': {'sizes':[(600,400)]},
|
||||
|
|