Fix label bounding box calculation to include glyph descenders [WIP] (ref #4308)
This commit is contained in:
parent
1ba1278b42
commit
d26346f335
7 changed files with 29 additions and 17 deletions
|
@ -360,7 +360,8 @@ struct harfbuzz_shaper
|
|||
// Try next font in fontset
|
||||
continue;
|
||||
}
|
||||
double max_glyph_height = 0;
|
||||
double ymin = 0;
|
||||
double ymax = 0;
|
||||
for (auto const& c_id : clusters)
|
||||
{
|
||||
auto const& c = glyphinfos[c_id];
|
||||
|
@ -382,19 +383,18 @@ struct harfbuzz_shaper
|
|||
// Overwrite default advance with better value provided by HarfBuzz
|
||||
g.unscaled_advance = gpos.x_advance;
|
||||
g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier);
|
||||
double tmp_height = g.height();
|
||||
ymin = std::min(ymin, g.ymin());
|
||||
ymax = std::max(ymax, g.ymax());
|
||||
if (g.face->is_color())
|
||||
{
|
||||
tmp_height = g.ymax();
|
||||
ymin = 0.0;
|
||||
}
|
||||
if (tmp_height > max_glyph_height)
|
||||
max_glyph_height = tmp_height;
|
||||
width_map[char_index] += g.advance();
|
||||
line.add_glyph(std::move(g), scale_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
line.update_max_char_height(max_glyph_height);
|
||||
line.update_max_char_height(ymin, ymax);
|
||||
break; // When we reach this point the current font had all glyphs.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,8 @@ struct icu_shaper
|
|||
std::size_t num_chars = static_cast<std::size_t>(num_char);
|
||||
shaped.releaseBuffer(length);
|
||||
bool shaped_status = true;
|
||||
double max_glyph_height = 0;
|
||||
double ymin = 0;
|
||||
double ymax = 0;
|
||||
if (U_SUCCESS(err) && (num_chars == length))
|
||||
{
|
||||
unsigned char_index = 0;
|
||||
|
@ -113,9 +114,8 @@ struct icu_shaper
|
|||
{
|
||||
g.face = face;
|
||||
g.scale_multiplier = size / face->get_face()->units_per_EM;
|
||||
double tmp_height = g.height();
|
||||
if (tmp_height > max_glyph_height)
|
||||
max_glyph_height = tmp_height;
|
||||
ymin = std::min(ymin, g.ymin());
|
||||
ymax = std::max(ymax, g.ymax());
|
||||
width_map[char_index++] += g.advance();
|
||||
line.add_glyph(std::move(g), scale_factor);
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ struct icu_shaper
|
|||
}
|
||||
if (!shaped_status)
|
||||
continue;
|
||||
line.update_max_char_height(max_glyph_height);
|
||||
line.update_max_char_height(ymin, ymax);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ class text_layout
|
|||
|
||||
inline rotation const& orientation() const { return orientation_; }
|
||||
inline pixel_position const& displacement() const { return displacement_; }
|
||||
inline double base_ajustment() const { return baseline_adjustment_; }
|
||||
inline box2d<double> const& bounds() const { return bounds_; }
|
||||
inline horizontal_alignment_e horizontal_alignment() const { return halign_; }
|
||||
pixel_position alignment_offset() const;
|
||||
|
@ -173,6 +174,7 @@ class text_layout
|
|||
bool repeat_wrap_char_ = false;
|
||||
bool rotate_displacement_ = false;
|
||||
double text_ratio_ = 0.0;
|
||||
double baseline_adjustment_ = 0.0;
|
||||
pixel_position displacement_ = {0, 0};
|
||||
box2d<double> bounds_ = {0, 0, 0, 0};
|
||||
|
||||
|
|
|
@ -65,7 +65,11 @@ class MAPNIK_DECL text_line : util::noncopyable
|
|||
double max_char_height() const { return max_char_height_; }
|
||||
|
||||
// Called for each font/style to update the maximum height of this line.
|
||||
void update_max_char_height(double max_char_height);
|
||||
void update_max_char_height(double ymin, double ymax);
|
||||
|
||||
// Verticall adjustment
|
||||
|
||||
double baseline_adjustment() const { return baseline_adjustment_;}
|
||||
|
||||
// Line height including line spacing.
|
||||
double line_height() const { return line_height_; }
|
||||
|
@ -88,6 +92,7 @@ class MAPNIK_DECL text_line : util::noncopyable
|
|||
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 baseline_adjustment_; // Adjustment to (0,0) origin
|
||||
double width_;
|
||||
double glyphs_width_;
|
||||
unsigned first_char_;
|
||||
|
|
|
@ -172,7 +172,6 @@ bool placement_finder::find_point_placement(pixel_position const& pos)
|
|||
|
||||
// Find text origin.
|
||||
pixel_position layout_center = pos + layout.displacement();
|
||||
|
||||
if (!base_point_set)
|
||||
{
|
||||
glyphs->set_base_point(layout_center);
|
||||
|
@ -180,9 +179,10 @@ bool placement_finder::find_point_placement(pixel_position const& pos)
|
|||
}
|
||||
|
||||
box2d<double> bbox = layout.bounds();
|
||||
bbox.re_center(layout_center.x, layout_center.y);
|
||||
|
||||
/* For point placements it is faster to just check the bounding box. */
|
||||
bbox.re_center(layout_center.x, layout_center.y - layout.base_ajustment());
|
||||
|
||||
// For point placements it is faster to just check the bounding box.
|
||||
if (collision(bbox, layouts_.text(), false))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -210,6 +210,7 @@ void text_layout::layout()
|
|||
displacement_ = scale_factor_ * displacement_ + alignment_offset();
|
||||
if (rotate_displacement_)
|
||||
displacement_ = displacement_.rotate(!orientation_);
|
||||
|
||||
// Find layout bounds, expanded for rotation
|
||||
rotated_box2d(bounds_, orientation_, displacement_, width_, height_);
|
||||
}
|
||||
|
@ -436,6 +437,7 @@ void text_layout::add_line(text_line&& line)
|
|||
line.set_first_line(true);
|
||||
}
|
||||
height_ += line.height();
|
||||
baseline_adjustment_ = line.baseline_adjustment();
|
||||
glyphs_count_ += line.size();
|
||||
width_ = std::max(width_, line.width());
|
||||
lines_.emplace_back(std::move(line));
|
||||
|
|
|
@ -30,6 +30,7 @@ text_line::text_line(unsigned first_char, unsigned last_char)
|
|||
: glyphs_()
|
||||
, line_height_(0.0)
|
||||
, max_char_height_(0.0)
|
||||
, baseline_adjustment_(0.0)
|
||||
, width_(0.0)
|
||||
, glyphs_width_(0.0)
|
||||
, first_char_(first_char)
|
||||
|
@ -42,6 +43,7 @@ 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_))
|
||||
, baseline_adjustment_(std::move(baseline_adjustment_))
|
||||
, width_(std::move(rhs.width_))
|
||||
, glyphs_width_(std::move(rhs.glyphs_width_))
|
||||
, first_char_(std::move(rhs.first_char_))
|
||||
|
@ -92,9 +94,10 @@ double text_line::height() const
|
|||
return line_height_;
|
||||
}
|
||||
|
||||
void text_line::update_max_char_height(double max_char_height)
|
||||
void text_line::update_max_char_height(double ymin, double ymax)
|
||||
{
|
||||
max_char_height_ = std::max(max_char_height_, max_char_height);
|
||||
max_char_height_ = std::max(max_char_height_, ymax - ymin);
|
||||
baseline_adjustment_ = ymin;
|
||||
}
|
||||
|
||||
void text_line::set_first_line(bool first_line)
|
||||
|
|
Loading…
Reference in a new issue