Merge pull request #2523 from mapycz/halign-adjust-immutable
halign adjust with immutability of style objects in mind
This commit is contained in:
commit
09f91a24a0
10 changed files with 63 additions and 14 deletions
|
@ -158,6 +158,7 @@ enum horizontal_alignment_enum
|
|||
H_MIDDLE,
|
||||
H_RIGHT,
|
||||
H_AUTO,
|
||||
H_ADJUST,
|
||||
horizontal_alignment_enum_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ bool placement_finder::find_line_placements(T & path, bool points)
|
|||
//horizontal_alignment_e halign = layouts_.back()->horizontal_alignment();
|
||||
|
||||
// halign == H_LEFT -> don't move
|
||||
if (horizontal_alignment_ == H_MIDDLE || horizontal_alignment_ == H_AUTO)
|
||||
if (horizontal_alignment_ == H_MIDDLE || horizontal_alignment_ == H_AUTO || horizontal_alignment_ == H_ADJUST)
|
||||
{
|
||||
if (!pp.forward(spacing / 2.0)) continue;
|
||||
}
|
||||
|
|
|
@ -123,6 +123,8 @@ public:
|
|||
double jalign_offset(double line_width) const;
|
||||
evaluated_format_properties_ptr & new_child_format_ptr(evaluated_format_properties_ptr const& p);
|
||||
|
||||
const_iterator longest_line() const;
|
||||
|
||||
private:
|
||||
void break_line(std::pair<unsigned, unsigned> && line_limits);
|
||||
void break_line_icu(std::pair<unsigned, unsigned> && line_limits);
|
||||
|
|
|
@ -57,6 +57,8 @@ public:
|
|||
|
||||
// Width of all glyphs including character spacing.
|
||||
double width() const { return width_; }
|
||||
// Width of all glyphs without character spacing.
|
||||
double glyphs_width() const { return glyphs_width_; }
|
||||
// Real line height. For first line: max_char_height(), for all others: line_height().
|
||||
double height() const;
|
||||
|
||||
|
@ -81,14 +83,18 @@ public:
|
|||
// Number of glyphs.
|
||||
unsigned size() const;
|
||||
|
||||
unsigned space_count() const { return space_count_; }
|
||||
|
||||
private:
|
||||
glyph_vector glyphs_;
|
||||
double line_height_; // Includes line spacing (returned by freetype)
|
||||
double max_char_height_; // Max height of any glyphs in line - calculated by shaper
|
||||
double width_;
|
||||
double glyphs_width_;
|
||||
unsigned first_char_;
|
||||
unsigned last_char_;
|
||||
bool first_line_;
|
||||
unsigned space_count_;
|
||||
};
|
||||
|
||||
} //namespace mapnik
|
||||
|
|
|
@ -137,6 +137,7 @@ static const char * horizontal_alignment_strings[] = {
|
|||
"middle",
|
||||
"right",
|
||||
"auto",
|
||||
"adjust",
|
||||
""
|
||||
};
|
||||
|
||||
|
|
|
@ -206,16 +206,30 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
|
|||
pixel_position const& layout_displacement = layout.displacement();
|
||||
double sign = (real_orientation == UPRIGHT_LEFT) ? -1 : 1;
|
||||
double offset = layout_displacement.y + 0.5 * sign * layout.height();
|
||||
double adjust_character_spacing = .0;
|
||||
double layout_width = layout.width();
|
||||
bool adjust = layout.horizontal_alignment() == H_ADJUST;
|
||||
|
||||
if (adjust)
|
||||
{
|
||||
text_layout::const_iterator longest_line = layout.longest_line();
|
||||
if (longest_line != layout.end())
|
||||
{
|
||||
adjust_character_spacing = (pp.length() - longest_line->glyphs_width()) / longest_line->space_count();
|
||||
layout_width = longest_line->glyphs_width() + longest_line->space_count() * adjust_character_spacing;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& line : layout)
|
||||
{
|
||||
// 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 & 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 is done
|
||||
double line_width = adjust ? (line.glyphs_width() + line.space_count() * adjust_character_spacing) : line.width();
|
||||
|
||||
if (!off_pp.move(sign * layout.jalign_offset(line.width()) - align_offset.x)) return false;
|
||||
if (!off_pp.move(sign * layout.jalign_offset(line_width) - align_offset.x)) return false;
|
||||
|
||||
double last_cluster_angle = 999;
|
||||
int current_cluster = -1;
|
||||
|
@ -228,11 +242,19 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
|
|||
{
|
||||
if (current_cluster != static_cast<int>(glyph.char_index))
|
||||
{
|
||||
if (!off_pp.move_to_distance(sign * (layout.cluster_width(current_cluster) + last_glyph_spacing)))
|
||||
return false;
|
||||
|
||||
if (adjust)
|
||||
{
|
||||
if (!off_pp.move(sign * (layout.cluster_width(current_cluster) + last_glyph_spacing)))
|
||||
return false;
|
||||
last_glyph_spacing = adjust_character_spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!off_pp.move_to_distance(sign * (layout.cluster_width(current_cluster) + last_glyph_spacing)))
|
||||
return false;
|
||||
last_glyph_spacing = glyph.format->character_spacing * scale_factor_;
|
||||
}
|
||||
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);
|
||||
|
@ -312,7 +334,7 @@ double placement_finder::normalize_angle(double angle)
|
|||
double placement_finder::get_spacing(double path_length, double layout_width) const
|
||||
{
|
||||
int num_labels = 1;
|
||||
if (text_props_->label_spacing > 0)
|
||||
if (horizontal_alignment_ != H_ADJUST && text_props_->label_spacing > 0)
|
||||
{
|
||||
num_labels = static_cast<int>(std::floor(
|
||||
path_length / (text_props_->label_spacing * scale_factor_ + layout_width)));
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
// ICU
|
||||
#include <unicode/brkiter.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
@ -489,6 +490,15 @@ double text_layout::jalign_offset(double line_width) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
text_layout::const_iterator text_layout::longest_line() const
|
||||
{
|
||||
return std::max_element(lines_.begin(), lines_.end(),
|
||||
[](text_line const& line1, text_line const& line2)
|
||||
{
|
||||
return line1.glyphs_width() < line2.glyphs_width();
|
||||
});
|
||||
}
|
||||
|
||||
void layout_container::add(text_layout_ptr layout)
|
||||
{
|
||||
text_ += layout->text();
|
||||
|
|
|
@ -31,19 +31,23 @@ text_line::text_line(unsigned first_char, unsigned last_char)
|
|||
line_height_(0.0),
|
||||
max_char_height_(0.0),
|
||||
width_(0.0),
|
||||
glyphs_width_(0.0),
|
||||
first_char_(first_char),
|
||||
last_char_(last_char),
|
||||
first_line_(false)
|
||||
first_line_(false),
|
||||
space_count_(0)
|
||||
{}
|
||||
|
||||
text_line::text_line( text_line && rhs)
|
||||
text_line::text_line(text_line && rhs)
|
||||
: glyphs_(std::move(rhs.glyphs_)),
|
||||
line_height_(std::move(rhs.line_height_)),
|
||||
max_char_height_(std::move(rhs.max_char_height_)),
|
||||
width_(std::move(rhs.width_)),
|
||||
glyphs_width_(std::move(rhs.glyphs_width_)),
|
||||
first_char_(std::move(rhs.first_char_)),
|
||||
last_char_(std::move(rhs.last_char_)),
|
||||
first_line_(std::move(rhs.first_line_)) {}
|
||||
first_line_(std::move(rhs.first_line_)),
|
||||
space_count_(std::move(rhs.space_count_)) {}
|
||||
|
||||
void text_line::add_glyph(glyph_info && glyph, double scale_factor_)
|
||||
{
|
||||
|
@ -52,11 +56,15 @@ void text_line::add_glyph(glyph_info && glyph, double scale_factor_)
|
|||
if (glyphs_.empty())
|
||||
{
|
||||
width_ = advance;
|
||||
glyphs_width_ = advance;
|
||||
space_count_ = 0;
|
||||
}
|
||||
else if (advance)
|
||||
{
|
||||
// Only add character spacing if the character is not a zero-width part of a cluster.
|
||||
width_ += advance + glyphs_.back().format->character_spacing * scale_factor_;
|
||||
glyphs_width_ += advance;
|
||||
space_count_++;
|
||||
}
|
||||
glyphs_.emplace_back(std::move(glyph));
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 30 KiB |
|
@ -185,9 +185,8 @@ files = {
|
|||
'text-bug2037': {'sizes': [(800, 300)], 'bbox': default_text_box},
|
||||
'text-expressionformat-color': {'sizes': [(800, 100)], 'bbox': default_text_box},
|
||||
'text-halign': {'sizes': [(800,800)], 'bbox': default_text_box},
|
||||
# disabled: https://github.com/mapnik/mapnik/pull/2426#issuecomment-58771864
|
||||
#'text-halign-adjust': {'sizes': [(800,800)], 'bbox': default_text_box},
|
||||
#'text-halign-adjust-multiline': {'sizes': [(800,800)], 'bbox': default_text_box},
|
||||
'text-halign-adjust': {'sizes': [(800,800)], 'bbox': default_text_box},
|
||||
'text-halign-adjust-multiline': {'sizes': [(800,800)], 'bbox': default_text_box},
|
||||
'text-vertical-alignment': {'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},
|
||||
|
|
Loading…
Add table
Reference in a new issue