Fix pango_text::set_maximum_height

Change back to handling the height in our code instead of expecting Pango to
handle it. Pango is still expected to handle the maximum width, as Pango needs
to handle the word-wrapping.

While writing f282eb7, I had noticed that set_maximum_height called
PangoLayout's pango_layout_set_height, and removed the apparently unnecessary
enforcement of the maximum height from our wrapper code. The documentation
added in this commit explains why that was incorrect.

This fixes the bug that some tooltips on the sidebar stopped working. The text
on that sidebar is densely packed, and while this commit makes no visual
change, it removes a few blank pixels of padding below the text. That extra
padding was sufficient for the next line's area to overlap, making
tooltips::add_tooltip remove the previously-added tooltip.

There's still a known issue with 800x600 resolution. At that resolution, the
side-flag is ellipsed (even if the unit has a short name), and the tooltips for
both the name and the flag are missing. The movement and defense tooltips (both
are on the line above the name and flag) are sometimes also missing in 800x600.

(cherry picked from commit 8304ada17c)
This commit is contained in:
Steve Cotton 2021-11-05 09:01:09 +01:00 committed by Steve Cotton
parent a9e534812d
commit 7c1a059c59

View file

@ -398,6 +398,11 @@ pango_text& pango_text::set_maximum_height(int height, bool multiline)
if(height != maximum_height_) {
// assert(context_);
// The maximum height is handled in this class' calculate_size() method.
//
// Although we also pass it to PangoLayout if multiline is true, the documentation of pango_layout_set_height
// makes me wonder whether we should avoid that function completely. For example, "at least one line is included
// in each paragraph regardless" and "may be changed in future, file a bug if you rely on the current behavior".
pango_layout_set_height(layout_.get(), !multiline ? -1 : height * PANGO_SCALE);
maximum_height_ = height;
calculation_dirty_ = true;
@ -418,6 +423,13 @@ pango_text& pango_text::set_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
surface_dirty_ = true;
}
// According to the docs of pango_layout_set_height, the behavior is undefined if a height other than -1 is combined
// with PANGO_ELLIPSIZE_NONE. Wesnoth's code currently always calls set_ellipse_mode after set_maximum_height, so do
// the cleanup here. The code in calculate_size() will still apply the maximum height after Pango's calculations.
if(ellipse_mode_ == PANGO_ELLIPSIZE_NONE) {
pango_layout_set_height(layout_.get(), -1);
}
return *this;
}
@ -569,6 +581,7 @@ PangoRectangle pango_text::calculate_size(PangoLayout& layout) const
<< " maximum_height " << maximum_height_
<< " result " << size
<< ".\n";
if(maximum_width != -1 && size.x + size.width > maximum_width) {
DBG_GUI_L << "pango_text::" << __func__
<< " text '" << gui2::debug_truncate(text_)
@ -577,6 +590,16 @@ PangoRectangle pango_text::calculate_size(PangoLayout& layout) const
<< ".\n";
}
// The maximum height is handled here instead of using the library - see the comments in set_maximum_height()
if(maximum_height_ != -1 && size.y + size.height > maximum_height_) {
DBG_GUI_L << "pango_text::" << __func__
<< " text '" << gui2::debug_truncate(text_)
<< " ' height " << size.y + size.height
<< " greater as the wanted maximum of " << maximum_height_
<< ".\n";
size.height = maximum_height_ - std::max(0, size.y);
}
return size;
}