2006-10-17 16:12:53 +02:00
|
|
|
/*****************************************************************************
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
*
|
2006-10-17 16:12:53 +02:00
|
|
|
* This file is part of Mapnik (c++ mapping toolkit)
|
|
|
|
*
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
* Copyright (C) 2013 Artem Pavlenko
|
2006-10-17 16:12:53 +02:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
2007-10-08 19:42:41 +02:00
|
|
|
//mapnik
|
2013-01-30 18:32:20 +01:00
|
|
|
#include <mapnik/debug.hpp>
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
#include <mapnik/label_collision_detector.hpp>
|
|
|
|
#include <mapnik/ctrans.hpp>
|
|
|
|
#include <mapnik/expression_evaluator.hpp>
|
2013-11-08 05:09:22 +01:00
|
|
|
#include <mapnik/text/placement_finder.hpp>
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
#include <mapnik/text/layout.hpp>
|
|
|
|
#include <mapnik/text/text_properties.hpp>
|
|
|
|
#include <mapnik/text/placements_list.hpp>
|
|
|
|
#include <mapnik/text/vertex_cache.hpp>
|
2007-11-02 13:50:15 +01:00
|
|
|
|
|
|
|
// agg
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
#include "agg_conv_clip_polyline.h"
|
2006-10-17 16:12:53 +02:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
// stl
|
2007-10-08 19:42:41 +02:00
|
|
|
#include <vector>
|
2006-11-28 11:38:56 +01:00
|
|
|
|
2006-10-17 16:12:53 +02:00
|
|
|
namespace mapnik
|
|
|
|
{
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
class tolerance_iterator
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
public:
|
|
|
|
tolerance_iterator(double label_position_tolerance, double spacing)
|
|
|
|
: tolerance_(label_position_tolerance > 0 ?
|
|
|
|
label_position_tolerance : spacing/2.0),
|
|
|
|
tolerance_delta_(std::max(1.0, tolerance_/100.0)),
|
|
|
|
value_(0),
|
|
|
|
initialized_(false),
|
|
|
|
values_tried_(0)
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
~tolerance_iterator()
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
//std::cout << "values tried:" << values_tried_ << "\n";
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
double get() const
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
return -value_;
|
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
bool next()
|
|
|
|
{
|
|
|
|
++values_tried_;
|
|
|
|
if (values_tried_ > 255)
|
|
|
|
{
|
|
|
|
/* This point should not be reached during normal operation. But I can think of
|
|
|
|
* cases where very bad spacing and or tolerance values are choosen and the
|
|
|
|
* placement finder tries an excessive number of placements.
|
|
|
|
* 255 is an arbitrarily chosen limit.
|
|
|
|
*/
|
|
|
|
MAPNIK_LOG_WARN(placement_finder) << "Tried a huge number of placements. Please check "
|
|
|
|
"'label-position-tolerance' and 'spacing' parameters "
|
|
|
|
"of your TextSymbolizers.\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!initialized_)
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
initialized_ = true;
|
|
|
|
return true; //Always return value 0 as the first value.
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (value_ == 0)
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
value_ = tolerance_delta_;
|
|
|
|
return true;
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
value_ = -value_;
|
|
|
|
if (value_ > 0)
|
|
|
|
{
|
|
|
|
value_ += tolerance_delta_;
|
|
|
|
}
|
|
|
|
if (value_ > tolerance_)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
private:
|
|
|
|
double tolerance_;
|
|
|
|
double tolerance_delta_;
|
|
|
|
double value_;
|
|
|
|
bool initialized_;
|
|
|
|
unsigned values_tried_;
|
|
|
|
};
|
2010-05-27 12:19:47 +02:00
|
|
|
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
placement_finder::placement_finder(feature_impl const& feature,
|
|
|
|
DetectorType &detector,
|
|
|
|
box2d<double> const& extent,
|
|
|
|
text_placement_info_ptr placement_info,
|
|
|
|
face_manager_freetype & font_manager,
|
|
|
|
double scale_factor)
|
|
|
|
: feature_(feature),
|
|
|
|
detector_(detector),
|
|
|
|
extent_(extent),
|
|
|
|
info_(placement_info),
|
|
|
|
valid_(true),
|
|
|
|
scale_factor_(scale_factor),
|
2014-01-30 12:31:47 +01:00
|
|
|
font_manager_(font_manager),
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
placements_(),
|
|
|
|
has_marker_(false),
|
|
|
|
marker_(),
|
|
|
|
marker_box_()
|
|
|
|
{
|
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
bool placement_finder::next_position()
|
2012-01-22 18:41:04 +01:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (!valid_)
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
MAPNIK_LOG_WARN(placement_finder) << "next_position() called while last call already returned false!\n";
|
|
|
|
return false;
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (!info_->next())
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
valid_ = false;
|
|
|
|
return false;
|
|
|
|
}
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
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();
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
return true;
|
2012-02-18 14:39:13 +01:00
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
text_upright_e placement_finder::simplify_upright(text_upright_e upright, double angle) const
|
2012-01-22 18:41:04 +01:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
if (upright == UPRIGHT_AUTO)
|
2012-03-19 17:12:53 +01:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
return (std::fabs(normalize_angle(angle)) > 0.5*M_PI) ? UPRIGHT_LEFT : UPRIGHT_RIGHT;
|
2011-02-28 14:17:46 +01:00
|
|
|
}
|
2014-01-30 12:31:47 +01:00
|
|
|
if (upright == UPRIGHT_LEFT_ONLY)
|
2012-03-19 17:12:53 +01:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
return UPRIGHT_LEFT;
|
2012-03-19 17:12:53 +01:00
|
|
|
}
|
2014-01-30 12:31:47 +01:00
|
|
|
if (upright == UPRIGHT_RIGHT_ONLY)
|
2012-03-19 17:12:53 +01:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
return UPRIGHT_RIGHT;
|
2011-02-28 14:17:46 +01:00
|
|
|
}
|
2014-01-30 12:31:47 +01:00
|
|
|
return upright;
|
2012-01-22 18:41:04 +01:00
|
|
|
}
|
2011-02-28 14:17:46 +01:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
bool placement_finder::find_point_placement(pixel_position const& pos)
|
2012-01-22 18:41:04 +01:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
glyph_positions_ptr glyphs = std::make_shared<glyph_positions>();
|
|
|
|
std::vector<box2d<double> > bboxes;
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
glyphs->reserve(layouts_.glyphs_count());
|
|
|
|
bboxes.reserve(layouts_.size());
|
|
|
|
|
|
|
|
bool base_point_set = false;
|
|
|
|
for (auto const& layout_ptr : layouts_)
|
2012-02-18 13:07:23 +01:00
|
|
|
{
|
2014-02-08 00:11:54 +01:00
|
|
|
text_layout const& layout = *layout_ptr;
|
2014-01-30 12:31:47 +01:00
|
|
|
rotation const& orientation = layout.orientation();
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
/* Find text origin. */
|
|
|
|
pixel_position layout_center = pos + layout.displacement();
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
if (!base_point_set)
|
|
|
|
{
|
|
|
|
glyphs->set_base_point(layout_center);
|
|
|
|
base_point_set = true;
|
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
box2d<double> bbox = layout.bounds();
|
|
|
|
bbox.re_center(layout_center.x, layout_center.y);
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
/* For point placements it is faster to just check the bounding box. */
|
|
|
|
if (collision(bbox)) return false;
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
if (layout.num_lines()) bboxes.push_back(std::move(bbox));
|
2012-02-18 14:39:13 +01:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
pixel_position layout_offset = layout_center - glyphs->get_base_point();
|
|
|
|
layout_offset.y = -layout_offset.y;
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
/* 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;
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
// 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)
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
y -= line.height(); //Automatically handles first line differently
|
|
|
|
x = layout.jalign_offset(line.width());
|
|
|
|
|
|
|
|
for (auto const& glyph : line)
|
2012-03-13 15:56:11 +01:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
// 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_;
|
|
|
|
}
|
2012-01-22 18:41:04 +01:00
|
|
|
}
|
2011-12-15 15:57:57 +01:00
|
|
|
}
|
2011-10-12 02:02:28 +02:00
|
|
|
}
|
2014-01-30 12:31:47 +01:00
|
|
|
|
|
|
|
/* 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());
|
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
placements_.push_back(glyphs);
|
2014-01-30 12:31:47 +01:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
return true;
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
template <typename T>
|
|
|
|
bool placement_finder::find_line_placements(T & path, bool points)
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
if (!layouts_.line_count()) return true; //TODO
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
vertex_cache pp(path);
|
|
|
|
|
|
|
|
bool success = false;
|
|
|
|
while (pp.next_subpath())
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (points)
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (pp.length() <= 0.001)
|
|
|
|
{
|
|
|
|
success = find_point_placement(pp.current_position()) || success;
|
|
|
|
continue;
|
|
|
|
}
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if ((pp.length() < info_->properties.minimum_path_length * scale_factor_)
|
|
|
|
||
|
|
|
|
(pp.length() <= 0.001) /* Clipping removed whole geometry */
|
|
|
|
||
|
2014-01-30 12:31:47 +01:00
|
|
|
(pp.length() < layouts_.width()))
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
double spacing = get_spacing(pp.length(), points ? 0. : layouts_.width());
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:01:57 +01:00
|
|
|
horizontal_alignment_e halign = info_->properties.layout_defaults->halign;
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (halign == H_LEFT)
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
// Don't move
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
else if (halign == H_MIDDLE || halign == H_AUTO)
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
pp.forward(spacing/2.0);
|
|
|
|
}
|
|
|
|
else if (halign == H_RIGHT)
|
|
|
|
{
|
|
|
|
pp.forward(pp.length());
|
|
|
|
}
|
|
|
|
path_move_dx(pp);
|
|
|
|
do
|
|
|
|
{
|
|
|
|
tolerance_iterator tolerance_offset(info_->properties.label_position_tolerance * scale_factor_, spacing); //TODO: Handle halign
|
|
|
|
while (tolerance_offset.next())
|
2007-11-02 13:50:15 +01:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
vertex_cache::scoped_state state(pp);
|
|
|
|
if (pp.move(tolerance_offset.get())
|
|
|
|
&& (
|
|
|
|
(points && find_point_placement(pp.current_position()))
|
|
|
|
|| (!points && single_line_placement(pp, info_->properties.upright))))
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
2008-01-21 04:08:18 +01:00
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
} while (pp.forward(spacing));
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
return success;
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e orientation)
|
|
|
|
{
|
|
|
|
/********************************************************************************
|
|
|
|
* IMPORTANT NOTE: See note about coordinate systems in find_point_placement()! *
|
|
|
|
********************************************************************************/
|
2014-01-30 12:31:47 +01:00
|
|
|
vertex_cache::scoped_state begin(pp);
|
2014-02-08 00:11:54 +01:00
|
|
|
text_upright_e real_orientation = simplify_upright(orientation, pp.angle());
|
2012-03-05 23:15:01 +01:00
|
|
|
|
2014-02-08 00:11:54 +01:00
|
|
|
glyph_positions_ptr glyphs = std::make_shared<glyph_positions>();
|
|
|
|
std::vector<box2d<double> > bboxes;
|
2014-01-30 12:31:47 +01:00
|
|
|
glyphs->reserve(layouts_.glyphs_count());
|
|
|
|
bboxes.reserve(layouts_.glyphs_count());
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
unsigned upside_down_glyph_count = 0;
|
2010-05-27 12:19:47 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
for (auto const& layout_ptr : layouts_)
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
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.;
|
|
|
|
|
|
|
|
for (auto const& line : layout)
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
//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)
|
2008-01-21 04:08:18 +01:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
if (current_cluster != static_cast<int>(glyph.char_index))
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
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;
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
2008-01-23 05:18:17 +01:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
if (std::abs(angle) > M_PI/2) ++upside_down_glyph_count;
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
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;
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
//See comment above
|
|
|
|
offset -= sign * line.height()/2;
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
2014-01-30 12:31:47 +01:00
|
|
|
|
|
|
|
if (upside_down_glyph_count > (layouts_.text().length() / 2))
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (orientation == UPRIGHT_AUTO)
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
//Try again with oposite orientation
|
2014-02-08 00:11:54 +01:00
|
|
|
begin.restore();
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
return single_line_placement(pp, real_orientation == UPRIGHT_RIGHT ? UPRIGHT_LEFT : UPRIGHT_RIGHT);
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
//upright==left_only or right_only and more than 50% of characters upside down => no placement
|
2014-01-30 12:31:47 +01:00
|
|
|
else if (orientation == UPRIGHT_LEFT_ONLY || orientation == UPRIGHT_RIGHT_ONLY)
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
return false;
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
2014-01-30 12:31:47 +01:00
|
|
|
|
|
|
|
for (box2d<double> const& box : bboxes)
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
{
|
2014-01-30 12:31:47 +01:00
|
|
|
detector_.insert(box, layouts_.text());
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
}
|
|
|
|
placements_.push_back(glyphs);
|
2014-01-30 12:31:47 +01:00
|
|
|
|
2014-02-08 00:11:54 +01:00
|
|
|
return true;
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
void placement_finder::path_move_dx(vertex_cache &pp)
|
|
|
|
{
|
2014-01-30 12:01:57 +01:00
|
|
|
double dx = info_->properties.layout_defaults->displacement.x * scale_factor_;
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (dx != 0.0)
|
|
|
|
{
|
|
|
|
vertex_cache::state state = pp.save_state();
|
|
|
|
if (!pp.move(dx)) pp.restore_state(state);
|
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
double placement_finder::normalize_angle(double angle)
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
while (angle >= M_PI)
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
angle -= 2.0 * M_PI;
|
|
|
|
}
|
|
|
|
while (angle < -M_PI)
|
|
|
|
{
|
|
|
|
angle += 2.0 * M_PI;
|
|
|
|
}
|
|
|
|
return angle;
|
|
|
|
}
|
2008-01-21 04:08:18 +01:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
double placement_finder::get_spacing(double path_length, double layout_width) const
|
|
|
|
{
|
|
|
|
int num_labels = 1;
|
|
|
|
if (info_->properties.label_spacing > 0)
|
|
|
|
{
|
|
|
|
num_labels = static_cast<int>(floor(
|
|
|
|
path_length / (info_->properties.label_spacing * scale_factor_ + layout_width)));
|
|
|
|
}
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (info_->properties.force_odd_labels && num_labels % 2 == 0)
|
|
|
|
{
|
|
|
|
--num_labels;
|
|
|
|
}
|
|
|
|
if (num_labels <= 0)
|
|
|
|
{
|
|
|
|
num_labels = 1;
|
|
|
|
}
|
|
|
|
return path_length / num_labels;
|
|
|
|
}
|
2012-12-11 22:56:25 +01:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
bool placement_finder::collision(const box2d<double> &box) const
|
|
|
|
{
|
|
|
|
if (!detector_.extent().intersects(box)
|
|
|
|
||
|
|
|
|
(info_->properties.avoid_edges && !extent_.contains(box))
|
|
|
|
||
|
|
|
|
(info_->properties.minimum_padding > 0 &&
|
|
|
|
!extent_.contains(box + (scale_factor_ * info_->properties.minimum_padding)))
|
|
|
|
||
|
|
|
|
(!info_->properties.allow_overlap &&
|
|
|
|
!detector_.has_point_placement(box, info_->properties.minimum_distance * scale_factor_))
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return true;
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
return false;
|
|
|
|
}
|
2012-02-02 02:53:35 +01:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
void placement_finder::set_marker(marker_info_ptr m, box2d<double> box, bool marker_unlocked, pixel_position const& marker_displacement)
|
|
|
|
{
|
|
|
|
marker_ = m;
|
|
|
|
marker_box_ = box * scale_factor_;
|
|
|
|
marker_displacement_ = marker_displacement * scale_factor_;
|
|
|
|
marker_unlocked_ = marker_unlocked;
|
|
|
|
has_marker_ = true;
|
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
|
|
|
|
bool placement_finder::add_marker(glyph_positions_ptr glyphs, pixel_position const& pos) const
|
|
|
|
{
|
|
|
|
pixel_position real_pos = (marker_unlocked_ ? pos : glyphs->get_base_point()) + marker_displacement_;
|
|
|
|
box2d<double> bbox = marker_box_;
|
|
|
|
bbox.move(real_pos.x, real_pos.y);
|
|
|
|
glyphs->set_marker(marker_, real_pos);
|
|
|
|
if (collision(bbox)) return false;
|
|
|
|
detector_.insert(bbox);
|
|
|
|
return true;
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
|
|
|
|
2014-01-30 12:31:47 +01:00
|
|
|
box2d<double> placement_finder::get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot)
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
/*
|
|
|
|
|
|
|
|
(0/ymax) (width/ymax)
|
|
|
|
***************
|
|
|
|
* *
|
|
|
|
(0/0)* *
|
|
|
|
* *
|
|
|
|
***************
|
|
|
|
(0/ymin) (width/ymin)
|
|
|
|
Add glyph offset in y direction, but not in x direction (as we use the full cluster width anyways)!
|
|
|
|
*/
|
2014-01-30 12:31:47 +01:00
|
|
|
double width = layout.cluster_width(glyph.char_index);
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
if (glyph.width <= 0) width = -width;
|
|
|
|
pixel_position tmp, tmp2;
|
|
|
|
tmp.set(0, glyph.ymax);
|
|
|
|
tmp = tmp.rotate(rot);
|
|
|
|
tmp2.set(width, glyph.ymax);
|
|
|
|
tmp2 = tmp2.rotate(rot);
|
|
|
|
box2d<double> bbox(tmp.x, -tmp.y,
|
|
|
|
tmp2.x, -tmp2.y);
|
|
|
|
tmp.set(width, glyph.ymin);
|
|
|
|
tmp = tmp.rotate(rot);
|
|
|
|
bbox.expand_to_include(tmp.x, -tmp.y);
|
|
|
|
tmp.set(0, glyph.ymin);
|
|
|
|
tmp = tmp.rotate(rot);
|
|
|
|
bbox.expand_to_include(tmp.x, -tmp.y);
|
|
|
|
pixel_position pos2 = pos + pixel_position(0, glyph.offset.y).rotate(rot);
|
|
|
|
bbox.move(pos2.x , -pos2.y);
|
|
|
|
return bbox;
|
|
|
|
}
|
2010-05-27 12:19:47 +02:00
|
|
|
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
/*********************************************************************************************/
|
2010-05-27 12:19:47 +02:00
|
|
|
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
glyph_positions::glyph_positions()
|
|
|
|
: data_(),
|
|
|
|
base_point_(),
|
|
|
|
marker_(),
|
|
|
|
marker_pos_(),
|
|
|
|
bbox_()
|
|
|
|
{
|
2010-05-27 12:19:47 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
glyph_positions::const_iterator glyph_positions::begin() const
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
return data_.begin();
|
|
|
|
}
|
2011-04-30 02:06:27 +02:00
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
glyph_positions::const_iterator glyph_positions::end() const
|
|
|
|
{
|
|
|
|
return data_.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
void glyph_positions::push_back(glyph_info const& glyph, pixel_position const offset, rotation const& rot)
|
|
|
|
{
|
|
|
|
data_.push_back(glyph_position(glyph, offset, rot));
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
void glyph_positions::reserve(unsigned count)
|
2010-05-27 12:19:47 +02:00
|
|
|
{
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
data_.reserve(count);
|
2010-05-27 12:19:47 +02:00
|
|
|
}
|
|
|
|
|
Improved support for international text
- Implementation by @herm for GSOC 2012 (http://mapnik.org/news/2012/10/06/gsoc2012-status9/)
- C++11 port, improvements, optimizations by @artemp
- Testing and integration with master by @springmeyer
- Thank you to all the support from @behdad along the way
- Thanks for help testing @toton6868, @stephankn, @nirvn, @mfrasca, @simonsonc and many others
Refs: #2073,#2070,#2038,#2037,#1953,#1820,#1819,#1714,#1634,#1547,#1532,#1319,#1208,#1154,#1146
2013-11-22 09:06:32 +01:00
|
|
|
pixel_position const& glyph_positions::get_base_point() const
|
|
|
|
{
|
|
|
|
return base_point_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void glyph_positions::set_base_point(pixel_position const base_point)
|
|
|
|
{
|
|
|
|
base_point_ = base_point;
|
|
|
|
}
|
|
|
|
|
|
|
|
void glyph_positions::set_marker(marker_info_ptr marker, pixel_position const& marker_pos)
|
|
|
|
{
|
|
|
|
marker_ = marker;
|
|
|
|
marker_pos_ = marker_pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
marker_info_ptr glyph_positions::marker() const
|
|
|
|
{
|
|
|
|
return marker_;
|
|
|
|
}
|
|
|
|
|
|
|
|
pixel_position const& glyph_positions::marker_pos() const
|
|
|
|
{
|
|
|
|
return marker_pos_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************************/
|
|
|
|
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
|
|
|
|
typedef coord_transform<CoordTransform,clipped_geometry_type> ClippedPathType;
|
|
|
|
typedef coord_transform<CoordTransform,geometry_type> PathType;
|
|
|
|
template bool placement_finder::find_line_placements<ClippedPathType>(ClippedPathType &, bool);
|
|
|
|
template bool placement_finder::find_line_placements<PathType>(PathType &, bool);
|
|
|
|
|
|
|
|
|
|
|
|
}// ns mapnik
|